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

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

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 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
« no previous file with comments | « net/proxy/polling_proxy_config_service.h ('k') | net/proxy/proxy_bypass_rules.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/proxy/polling_proxy_config_service.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/observer_list.h"
12 #include "base/profiler/scoped_tracker.h"
13 #include "base/synchronization/lock.h"
14 #include "base/threading/worker_pool.h"
15 #include "net/proxy/proxy_config.h"
16
17 namespace net {
18
19 // Reference-counted wrapper that does all the work (needs to be
20 // reference-counted since we post tasks between threads; may outlive
21 // the parent PollingProxyConfigService).
22 class PollingProxyConfigService::Core
23 : public base::RefCountedThreadSafe<PollingProxyConfigService::Core> {
24 public:
25 Core(base::TimeDelta poll_interval,
26 GetConfigFunction get_config_func)
27 : get_config_func_(get_config_func),
28 poll_interval_(poll_interval),
29 have_initialized_origin_loop_(false),
30 has_config_(false),
31 poll_task_outstanding_(false),
32 poll_task_queued_(false) {
33 }
34
35 // Called when the parent PollingProxyConfigService is destroyed
36 // (observers should not be called past this point).
37 void Orphan() {
38 base::AutoLock l(lock_);
39 origin_loop_proxy_ = NULL;
40 }
41
42 bool GetLatestProxyConfig(ProxyConfig* config) {
43 LazyInitializeOriginLoop();
44 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
45
46 OnLazyPoll();
47
48 // If we have already retrieved the proxy settings (on worker thread)
49 // then return what we last saw.
50 if (has_config_) {
51 *config = last_config_;
52 return true;
53 }
54 return false;
55 }
56
57 void AddObserver(Observer* observer) {
58 LazyInitializeOriginLoop();
59 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
60 observers_.AddObserver(observer);
61 }
62
63 void RemoveObserver(Observer* observer) {
64 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
65 observers_.RemoveObserver(observer);
66 }
67
68 // Check for a new configuration if enough time has elapsed.
69 void OnLazyPoll() {
70 LazyInitializeOriginLoop();
71 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
72
73 if (last_poll_time_.is_null() ||
74 (base::TimeTicks::Now() - last_poll_time_) > poll_interval_) {
75 CheckForChangesNow();
76 }
77 }
78
79 void CheckForChangesNow() {
80 LazyInitializeOriginLoop();
81 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
82
83 if (poll_task_outstanding_) {
84 // Only allow one task to be outstanding at a time. If we get a poll
85 // request while we are busy, we will defer it until the current poll
86 // completes.
87 poll_task_queued_ = true;
88 return;
89 }
90
91 last_poll_time_ = base::TimeTicks::Now();
92 poll_task_outstanding_ = true;
93 poll_task_queued_ = false;
94 base::WorkerPool::PostTask(
95 FROM_HERE,
96 base::Bind(&Core::PollOnWorkerThread, this, get_config_func_),
97 true);
98 }
99
100 private:
101 friend class base::RefCountedThreadSafe<Core>;
102 ~Core() {}
103
104 void PollOnWorkerThread(GetConfigFunction func) {
105 ProxyConfig config;
106 func(&config);
107
108 base::AutoLock l(lock_);
109 if (origin_loop_proxy_.get()) {
110 origin_loop_proxy_->PostTask(
111 FROM_HERE, base::Bind(&Core::GetConfigCompleted, this, config));
112 }
113 }
114
115 // Called after the worker thread has finished retrieving a configuration.
116 void GetConfigCompleted(const ProxyConfig& config) {
117 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455942 is
118 // fixed.
119 tracked_objects::ScopedTracker tracking_profile(
120 FROM_HERE_WITH_EXPLICIT_FUNCTION(
121 "455942 PollingProxyConfigService::Core::GetConfigCompleted"));
122 DCHECK(poll_task_outstanding_);
123 poll_task_outstanding_ = false;
124
125 if (!origin_loop_proxy_.get())
126 return; // Was orphaned (parent has already been destroyed).
127
128 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
129
130 if (!has_config_ || !last_config_.Equals(config)) {
131 // If the configuration has changed, notify the observers.
132 has_config_ = true;
133 last_config_ = config;
134 FOR_EACH_OBSERVER(Observer, observers_,
135 OnProxyConfigChanged(config,
136 ProxyConfigService::CONFIG_VALID));
137 }
138
139 if (poll_task_queued_)
140 CheckForChangesNow();
141 }
142
143 void LazyInitializeOriginLoop() {
144 // TODO(eroman): Really this should be done in the constructor, but right
145 // now chrome is constructing the ProxyConfigService on the
146 // UI thread so we can't cache the IO thread for the purpose
147 // of DCHECKs until the first call is made.
148 if (!have_initialized_origin_loop_) {
149 origin_loop_proxy_ = base::MessageLoopProxy::current();
150 have_initialized_origin_loop_ = true;
151 }
152 }
153
154 GetConfigFunction get_config_func_;
155 ObserverList<Observer> observers_;
156 ProxyConfig last_config_;
157 base::TimeTicks last_poll_time_;
158 base::TimeDelta poll_interval_;
159
160 base::Lock lock_;
161 scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_;
162
163 bool have_initialized_origin_loop_;
164 bool has_config_;
165 bool poll_task_outstanding_;
166 bool poll_task_queued_;
167 };
168
169 void PollingProxyConfigService::AddObserver(Observer* observer) {
170 core_->AddObserver(observer);
171 }
172
173 void PollingProxyConfigService::RemoveObserver(Observer* observer) {
174 core_->RemoveObserver(observer);
175 }
176
177 ProxyConfigService::ConfigAvailability
178 PollingProxyConfigService::GetLatestProxyConfig(ProxyConfig* config) {
179 return core_->GetLatestProxyConfig(config) ? CONFIG_VALID : CONFIG_PENDING;
180 }
181
182 void PollingProxyConfigService::OnLazyPoll() {
183 core_->OnLazyPoll();
184 }
185
186 PollingProxyConfigService::PollingProxyConfigService(
187 base::TimeDelta poll_interval,
188 GetConfigFunction get_config_func)
189 : core_(new Core(poll_interval, get_config_func)) {
190 }
191
192 PollingProxyConfigService::~PollingProxyConfigService() {
193 core_->Orphan();
194 }
195
196 void PollingProxyConfigService::CheckForChangesNow() {
197 core_->CheckForChangesNow();
198 }
199
200 } // namespace net
OLDNEW
« no previous file with comments | « net/proxy/polling_proxy_config_service.h ('k') | net/proxy/proxy_bypass_rules.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698