Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: net/proxy/polling_proxy_config_service.cc

Issue 1141573002: [net/proxy] Usage of ThreadTaskRunnerHandle & SingleThreadTaskRunner instead of MLP (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/proxy/polling_proxy_config_service.h" 5 #include "net/proxy/polling_proxy_config_service.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/observer_list.h" 10 #include "base/observer_list.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/synchronization/lock.h" 12 #include "base/synchronization/lock.h"
13 #include "base/thread_task_runner_handle.h"
13 #include "base/threading/worker_pool.h" 14 #include "base/threading/worker_pool.h"
14 #include "net/proxy/proxy_config.h" 15 #include "net/proxy/proxy_config.h"
15 16
16 namespace net { 17 namespace net {
17 18
18 // Reference-counted wrapper that does all the work (needs to be 19 // Reference-counted wrapper that does all the work (needs to be
19 // reference-counted since we post tasks between threads; may outlive 20 // reference-counted since we post tasks between threads; may outlive
20 // the parent PollingProxyConfigService). 21 // the parent PollingProxyConfigService).
21 class PollingProxyConfigService::Core 22 class PollingProxyConfigService::Core
22 : public base::RefCountedThreadSafe<PollingProxyConfigService::Core> { 23 : public base::RefCountedThreadSafe<PollingProxyConfigService::Core> {
23 public: 24 public:
24 Core(base::TimeDelta poll_interval, 25 Core(base::TimeDelta poll_interval, GetConfigFunction get_config_func)
25 GetConfigFunction get_config_func)
26 : get_config_func_(get_config_func), 26 : get_config_func_(get_config_func),
27 poll_interval_(poll_interval), 27 poll_interval_(poll_interval),
28 have_initialized_origin_loop_(false), 28 have_initialized_origin_runner_(false),
29 has_config_(false), 29 has_config_(false),
30 poll_task_outstanding_(false), 30 poll_task_outstanding_(false),
31 poll_task_queued_(false) { 31 poll_task_queued_(false) {}
32 }
33 32
34 // Called when the parent PollingProxyConfigService is destroyed 33 // Called when the parent PollingProxyConfigService is destroyed
35 // (observers should not be called past this point). 34 // (observers should not be called past this point).
36 void Orphan() { 35 void Orphan() {
37 base::AutoLock l(lock_); 36 base::AutoLock l(lock_);
38 origin_loop_proxy_ = NULL; 37 origin_task_runner_ = NULL;
39 } 38 }
40 39
41 bool GetLatestProxyConfig(ProxyConfig* config) { 40 bool GetLatestProxyConfig(ProxyConfig* config) {
42 LazyInitializeOriginLoop(); 41 LazyInitializeOriginLoop();
43 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 42 DCHECK(origin_task_runner_->BelongsToCurrentThread());
44 43
45 OnLazyPoll(); 44 OnLazyPoll();
46 45
47 // If we have already retrieved the proxy settings (on worker thread) 46 // If we have already retrieved the proxy settings (on worker thread)
48 // then return what we last saw. 47 // then return what we last saw.
49 if (has_config_) { 48 if (has_config_) {
50 *config = last_config_; 49 *config = last_config_;
51 return true; 50 return true;
52 } 51 }
53 return false; 52 return false;
54 } 53 }
55 54
56 void AddObserver(Observer* observer) { 55 void AddObserver(Observer* observer) {
57 LazyInitializeOriginLoop(); 56 LazyInitializeOriginLoop();
58 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 57 DCHECK(origin_task_runner_->BelongsToCurrentThread());
59 observers_.AddObserver(observer); 58 observers_.AddObserver(observer);
60 } 59 }
61 60
62 void RemoveObserver(Observer* observer) { 61 void RemoveObserver(Observer* observer) {
63 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 62 DCHECK(origin_task_runner_->BelongsToCurrentThread());
64 observers_.RemoveObserver(observer); 63 observers_.RemoveObserver(observer);
65 } 64 }
66 65
67 // Check for a new configuration if enough time has elapsed. 66 // Check for a new configuration if enough time has elapsed.
68 void OnLazyPoll() { 67 void OnLazyPoll() {
69 LazyInitializeOriginLoop(); 68 LazyInitializeOriginLoop();
70 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 69 DCHECK(origin_task_runner_->BelongsToCurrentThread());
71 70
72 if (last_poll_time_.is_null() || 71 if (last_poll_time_.is_null() ||
73 (base::TimeTicks::Now() - last_poll_time_) > poll_interval_) { 72 (base::TimeTicks::Now() - last_poll_time_) > poll_interval_) {
74 CheckForChangesNow(); 73 CheckForChangesNow();
75 } 74 }
76 } 75 }
77 76
78 void CheckForChangesNow() { 77 void CheckForChangesNow() {
79 LazyInitializeOriginLoop(); 78 LazyInitializeOriginLoop();
80 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 79 DCHECK(origin_task_runner_->BelongsToCurrentThread());
81 80
82 if (poll_task_outstanding_) { 81 if (poll_task_outstanding_) {
83 // Only allow one task to be outstanding at a time. If we get a poll 82 // Only allow one task to be outstanding at a time. If we get a poll
84 // request while we are busy, we will defer it until the current poll 83 // request while we are busy, we will defer it until the current poll
85 // completes. 84 // completes.
86 poll_task_queued_ = true; 85 poll_task_queued_ = true;
87 return; 86 return;
88 } 87 }
89 88
90 last_poll_time_ = base::TimeTicks::Now(); 89 last_poll_time_ = base::TimeTicks::Now();
91 poll_task_outstanding_ = true; 90 poll_task_outstanding_ = true;
92 poll_task_queued_ = false; 91 poll_task_queued_ = false;
93 base::WorkerPool::PostTask( 92 base::WorkerPool::PostTask(
94 FROM_HERE, 93 FROM_HERE,
95 base::Bind(&Core::PollOnWorkerThread, this, get_config_func_), 94 base::Bind(&Core::PollOnWorkerThread, this, get_config_func_),
96 true); 95 true);
97 } 96 }
98 97
99 private: 98 private:
100 friend class base::RefCountedThreadSafe<Core>; 99 friend class base::RefCountedThreadSafe<Core>;
101 ~Core() {} 100 ~Core() {}
102 101
103 void PollOnWorkerThread(GetConfigFunction func) { 102 void PollOnWorkerThread(GetConfigFunction func) {
104 ProxyConfig config; 103 ProxyConfig config;
105 func(&config); 104 func(&config);
106 105
107 base::AutoLock l(lock_); 106 base::AutoLock l(lock_);
108 if (origin_loop_proxy_.get()) { 107 if (origin_task_runner_.get()) {
109 origin_loop_proxy_->PostTask( 108 origin_task_runner_->PostTask(
110 FROM_HERE, base::Bind(&Core::GetConfigCompleted, this, config)); 109 FROM_HERE, base::Bind(&Core::GetConfigCompleted, this, config));
111 } 110 }
112 } 111 }
113 112
114 // Called after the worker thread has finished retrieving a configuration. 113 // Called after the worker thread has finished retrieving a configuration.
115 void GetConfigCompleted(const ProxyConfig& config) { 114 void GetConfigCompleted(const ProxyConfig& config) {
116 DCHECK(poll_task_outstanding_); 115 DCHECK(poll_task_outstanding_);
117 poll_task_outstanding_ = false; 116 poll_task_outstanding_ = false;
118 117
119 if (!origin_loop_proxy_.get()) 118 if (!origin_task_runner_.get())
120 return; // Was orphaned (parent has already been destroyed). 119 return; // Was orphaned (parent has already been destroyed).
121 120
122 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 121 DCHECK(origin_task_runner_->BelongsToCurrentThread());
123 122
124 if (!has_config_ || !last_config_.Equals(config)) { 123 if (!has_config_ || !last_config_.Equals(config)) {
125 // If the configuration has changed, notify the observers. 124 // If the configuration has changed, notify the observers.
126 has_config_ = true; 125 has_config_ = true;
127 last_config_ = config; 126 last_config_ = config;
128 FOR_EACH_OBSERVER(Observer, observers_, 127 FOR_EACH_OBSERVER(Observer, observers_,
129 OnProxyConfigChanged(config, 128 OnProxyConfigChanged(config,
130 ProxyConfigService::CONFIG_VALID)); 129 ProxyConfigService::CONFIG_VALID));
131 } 130 }
132 131
133 if (poll_task_queued_) 132 if (poll_task_queued_)
134 CheckForChangesNow(); 133 CheckForChangesNow();
135 } 134 }
136 135
137 void LazyInitializeOriginLoop() { 136 void LazyInitializeOriginLoop() {
138 // TODO(eroman): Really this should be done in the constructor, but right 137 // TODO(eroman): Really this should be done in the constructor, but right
139 // now chrome is constructing the ProxyConfigService on the 138 // now chrome is constructing the ProxyConfigService on the
140 // UI thread so we can't cache the IO thread for the purpose 139 // UI thread so we can't cache the IO thread for the purpose
141 // of DCHECKs until the first call is made. 140 // of DCHECKs until the first call is made.
142 if (!have_initialized_origin_loop_) { 141 if (!have_initialized_origin_runner_) {
143 origin_loop_proxy_ = base::MessageLoopProxy::current(); 142 origin_task_runner_ = base::ThreadTaskRunnerHandle::Get();
144 have_initialized_origin_loop_ = true; 143 have_initialized_origin_runner_ = true;
145 } 144 }
146 } 145 }
147 146
148 GetConfigFunction get_config_func_; 147 GetConfigFunction get_config_func_;
149 ObserverList<Observer> observers_; 148 ObserverList<Observer> observers_;
150 ProxyConfig last_config_; 149 ProxyConfig last_config_;
151 base::TimeTicks last_poll_time_; 150 base::TimeTicks last_poll_time_;
152 base::TimeDelta poll_interval_; 151 base::TimeDelta poll_interval_;
153 152
154 base::Lock lock_; 153 base::Lock lock_;
155 scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_; 154 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
156 155
157 bool have_initialized_origin_loop_; 156 bool have_initialized_origin_runner_;
158 bool has_config_; 157 bool has_config_;
159 bool poll_task_outstanding_; 158 bool poll_task_outstanding_;
160 bool poll_task_queued_; 159 bool poll_task_queued_;
161 }; 160 };
162 161
163 void PollingProxyConfigService::AddObserver(Observer* observer) { 162 void PollingProxyConfigService::AddObserver(Observer* observer) {
164 core_->AddObserver(observer); 163 core_->AddObserver(observer);
165 } 164 }
166 165
167 void PollingProxyConfigService::RemoveObserver(Observer* observer) { 166 void PollingProxyConfigService::RemoveObserver(Observer* observer) {
(...skipping 17 matching lines...) Expand all
185 184
186 PollingProxyConfigService::~PollingProxyConfigService() { 185 PollingProxyConfigService::~PollingProxyConfigService() {
187 core_->Orphan(); 186 core_->Orphan();
188 } 187 }
189 188
190 void PollingProxyConfigService::CheckForChangesNow() { 189 void PollingProxyConfigService::CheckForChangesNow() {
191 core_->CheckForChangesNow(); 190 core_->CheckForChangesNow();
192 } 191 }
193 192
194 } // namespace net 193 } // namespace net
OLDNEW
« no previous file with comments | « net/proxy/network_delegate_error_observer_unittest.cc ('k') | net/proxy/proxy_config_service_linux_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698