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

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

Issue 6597070: Allow ProxyConfigService to report "no configuration set" (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comment Created 9 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/message_loop_proxy.h" 7 #include "base/message_loop_proxy.h"
8 #include "base/observer_list.h" 8 #include "base/observer_list.h"
9 #include "base/scoped_ptr.h" 9 #include "base/scoped_ptr.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
11 #include "base/threading/worker_pool.h" 11 #include "base/threading/worker_pool.h"
12 #include "net/proxy/proxy_config.h" 12 #include "net/proxy/proxy_config.h"
13 13
14 namespace net { 14 namespace net {
15 15
16 // Reference-counted wrapper that does all the work (needs to be 16 // Reference-counted wrapper that does all the work (needs to be
17 // reference-counted since we post tasks between threads; may outlive 17 // reference-counted since we post tasks between threads; may outlive
18 // the parent PollingProxyConfigService). 18 // the parent PollingProxyConfigService).
19 class PollingProxyConfigService::Core 19 class PollingProxyConfigService::Core
20 : public base::RefCountedThreadSafe<PollingProxyConfigService::Core> { 20 : public base::RefCountedThreadSafe<PollingProxyConfigService::Core> {
21 public: 21 public:
22 Core(base::TimeDelta poll_interval, 22 Core(base::TimeDelta poll_interval,
23 GetConfigFunction get_config_func) 23 GetConfigFunction get_config_func)
24 : get_config_func_(get_config_func), 24 : get_config_func_(get_config_func),
25 poll_interval_(poll_interval), 25 poll_interval_(poll_interval),
26 have_initialized_origin_loop_(false), 26 have_initialized_origin_loop_(false),
27 has_config_(false), 27 config_availability_(ProxyConfigService::CONFIG_PENDING),
28 poll_task_outstanding_(false), 28 poll_task_outstanding_(false),
29 poll_task_queued_(false) { 29 poll_task_queued_(false) {
30 } 30 }
31 31
32 // Called when the parent PollingProxyConfigService is destroyed 32 // Called when the parent PollingProxyConfigService is destroyed
33 // (observers should not be called past this point). 33 // (observers should not be called past this point).
34 void Orphan() { 34 void Orphan() {
35 base::AutoLock l(lock_); 35 base::AutoLock l(lock_);
36 origin_loop_proxy_ = NULL; 36 origin_loop_proxy_ = NULL;
37 } 37 }
38 38
39 bool GetLatestProxyConfig(ProxyConfig* config) { 39 ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
40 ProxyConfig* config) {
40 LazyInitializeOriginLoop(); 41 LazyInitializeOriginLoop();
41 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 42 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
42 43
43 OnLazyPoll(); 44 OnLazyPoll();
44 45
45 // If we have already retrieved the proxy settings (on worker thread) 46 // If we have already retrieved the proxy settings (on worker thread)
46 // then return what we last saw. 47 // then return what we last saw.
47 if (has_config_) { 48 if (config_availability_ == ProxyConfigService::CONFIG_VALID)
48 *config = last_config_; 49 *config = last_config_;
49 return true; 50
50 } 51 return config_availability_;
51 return false;
52 } 52 }
53 53
54 void AddObserver(Observer* observer) { 54 void AddObserver(Observer* observer) {
55 LazyInitializeOriginLoop(); 55 LazyInitializeOriginLoop();
56 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 56 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
57 observers_.AddObserver(observer); 57 observers_.AddObserver(observer);
58 } 58 }
59 59
60 void RemoveObserver(Observer* observer) { 60 void RemoveObserver(Observer* observer) {
61 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 61 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
(...skipping 28 matching lines...) Expand all
90 poll_task_queued_ = false; 90 poll_task_queued_ = false;
91 base::WorkerPool::PostTask( 91 base::WorkerPool::PostTask(
92 FROM_HERE, 92 FROM_HERE,
93 NewRunnableMethod(this, &Core::PollOnWorkerThread, get_config_func_), 93 NewRunnableMethod(this, &Core::PollOnWorkerThread, get_config_func_),
94 true); 94 true);
95 } 95 }
96 96
97 private: 97 private:
98 void PollOnWorkerThread(GetConfigFunction func) { 98 void PollOnWorkerThread(GetConfigFunction func) {
99 ProxyConfig config; 99 ProxyConfig config;
100 func(&config); 100 ProxyConfigService::ConfigAvailability available = func(&config);
eroman 2011/03/16 01:30:00 Please add a DCHECK/CHECK that |available| != CONF
Mattias Nissler (ping if slow) 2011/03/16 17:40:00 Done.
101 101
102 base::AutoLock l(lock_); 102 base::AutoLock l(lock_);
103 if (origin_loop_proxy_) { 103 if (origin_loop_proxy_) {
104 origin_loop_proxy_->PostTask( 104 origin_loop_proxy_->PostTask(
105 FROM_HERE, 105 FROM_HERE,
106 NewRunnableMethod(this, &Core::GetConfigCompleted, config)); 106 NewRunnableMethod(this, &Core::GetConfigCompleted,
107 config, available));
107 } 108 }
108 } 109 }
109 110
110 // Called after the worker thread has finished retrieving a configuration. 111 // Called after the worker thread has finished retrieving a configuration.
111 void GetConfigCompleted(const ProxyConfig& config) { 112 void GetConfigCompleted(
113 const ProxyConfig& config,
114 ProxyConfigService::ConfigAvailability available) {
112 DCHECK(poll_task_outstanding_); 115 DCHECK(poll_task_outstanding_);
113 poll_task_outstanding_ = false; 116 poll_task_outstanding_ = false;
114 117
115 if (!origin_loop_proxy_) 118 if (!origin_loop_proxy_)
116 return; // Was orphaned (parent has already been destroyed). 119 return; // Was orphaned (parent has already been destroyed).
117 120
118 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 121 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
119 122
120 if (!has_config_ || !last_config_.Equals(config)) { 123 if (config_availability_ != available ||
124 (available == ProxyConfigService::CONFIG_VALID &&
125 !last_config_.Equals(config))) {
121 // If the configuration has changed, notify the observers. 126 // If the configuration has changed, notify the observers.
122 has_config_ = true; 127 config_availability_ = available;
123 last_config_ = config; 128 last_config_ = config;
124 FOR_EACH_OBSERVER(Observer, observers_, OnProxyConfigChanged(config)); 129 FOR_EACH_OBSERVER(Observer, observers_,
130 OnProxyConfigChanged(last_config_,
131 config_availability_));
125 } 132 }
126 133
127 if (poll_task_queued_) 134 if (poll_task_queued_)
128 CheckForChangesNow(); 135 CheckForChangesNow();
129 } 136 }
130 137
131 void LazyInitializeOriginLoop() { 138 void LazyInitializeOriginLoop() {
132 // TODO(eroman): Really this should be done in the constructor, but right 139 // TODO(eroman): Really this should be done in the constructor, but right
133 // now chrome is constructing the ProxyConfigService on the 140 // now chrome is constructing the ProxyConfigService on the
134 // UI thread so we can't cache the IO thread for the purpose 141 // UI thread so we can't cache the IO thread for the purpose
135 // of DCHECKs until the first call is made. 142 // of DCHECKs until the first call is made.
136 if (!have_initialized_origin_loop_) { 143 if (!have_initialized_origin_loop_) {
137 origin_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread(); 144 origin_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread();
138 have_initialized_origin_loop_ = true; 145 have_initialized_origin_loop_ = true;
139 } 146 }
140 } 147 }
141 148
142 GetConfigFunction get_config_func_; 149 GetConfigFunction get_config_func_;
143 ObserverList<Observer> observers_; 150 ObserverList<Observer> observers_;
144 ProxyConfig last_config_; 151 ProxyConfig last_config_;
145 base::TimeTicks last_poll_time_; 152 base::TimeTicks last_poll_time_;
146 base::TimeDelta poll_interval_; 153 base::TimeDelta poll_interval_;
147 154
148 base::Lock lock_; 155 base::Lock lock_;
149 scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_; 156 scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_;
150 157
151 bool have_initialized_origin_loop_; 158 bool have_initialized_origin_loop_;
152 bool has_config_; 159 ProxyConfigService::ConfigAvailability config_availability_;
153 bool poll_task_outstanding_; 160 bool poll_task_outstanding_;
154 bool poll_task_queued_; 161 bool poll_task_queued_;
155 }; 162 };
156 163
157 void PollingProxyConfigService::AddObserver(Observer* observer) { 164 void PollingProxyConfigService::AddObserver(Observer* observer) {
158 core_->AddObserver(observer); 165 core_->AddObserver(observer);
159 } 166 }
160 167
161 void PollingProxyConfigService::RemoveObserver(Observer* observer) { 168 void PollingProxyConfigService::RemoveObserver(Observer* observer) {
162 core_->RemoveObserver(observer); 169 core_->RemoveObserver(observer);
163 } 170 }
164 171
165 bool PollingProxyConfigService::GetLatestProxyConfig(ProxyConfig* config) { 172 ProxyConfigService::ConfigAvailability
173 PollingProxyConfigService::GetLatestProxyConfig(ProxyConfig* config) {
166 return core_->GetLatestProxyConfig(config); 174 return core_->GetLatestProxyConfig(config);
167 } 175 }
168 176
169 void PollingProxyConfigService::OnLazyPoll() { 177 void PollingProxyConfigService::OnLazyPoll() {
170 core_->OnLazyPoll(); 178 core_->OnLazyPoll();
171 } 179 }
172 180
173 PollingProxyConfigService::PollingProxyConfigService( 181 PollingProxyConfigService::PollingProxyConfigService(
174 base::TimeDelta poll_interval, 182 base::TimeDelta poll_interval,
175 GetConfigFunction get_config_func) 183 GetConfigFunction get_config_func)
176 : core_(new Core(poll_interval, get_config_func)) { 184 : core_(new Core(poll_interval, get_config_func)) {
177 } 185 }
178 186
179 PollingProxyConfigService::~PollingProxyConfigService() { 187 PollingProxyConfigService::~PollingProxyConfigService() {
180 core_->Orphan(); 188 core_->Orphan();
181 } 189 }
182 190
183 void PollingProxyConfigService::CheckForChangesNow() { 191 void PollingProxyConfigService::CheckForChangesNow() {
184 core_->CheckForChangesNow(); 192 core_->CheckForChangesNow();
185 } 193 }
186 194
187 } // namespace net 195 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698