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

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

Issue 848006: Generalize the net module's LoadLog facility from a passive container, to an event stream (NetLog). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Split up RequestTracker into ConnectJobTracker+RequestTracker+RequestTrackerBase, address comments Created 10 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/single_threaded_proxy_resolver.h" 5 #include "net/proxy/single_threaded_proxy_resolver.h"
6 6
7 #include "base/thread.h" 7 #include "base/thread.h"
8 #include "net/base/load_log.h" 8 #include "net/base/net_log.h"
9 #include "net/base/net_errors.h" 9 #include "net/base/net_errors.h"
10 #include "net/proxy/proxy_info.h" 10 #include "net/proxy/proxy_info.h"
11 11
12 namespace net { 12 namespace net {
13 13
14 namespace { 14 namespace {
15 15
16 class PurgeMemoryTask : public base::RefCountedThreadSafe<PurgeMemoryTask> { 16 class PurgeMemoryTask : public base::RefCountedThreadSafe<PurgeMemoryTask> {
17 public: 17 public:
18 explicit PurgeMemoryTask(ProxyResolver* resolver) : resolver_(resolver) {} 18 explicit PurgeMemoryTask(ProxyResolver* resolver) : resolver_(resolver) {}
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 class SingleThreadedProxyResolver::Job 103 class SingleThreadedProxyResolver::Job
104 : public base::RefCountedThreadSafe<SingleThreadedProxyResolver::Job> { 104 : public base::RefCountedThreadSafe<SingleThreadedProxyResolver::Job> {
105 public: 105 public:
106 // |coordinator| -- the SingleThreadedProxyResolver that owns this job. 106 // |coordinator| -- the SingleThreadedProxyResolver that owns this job.
107 // |url| -- the URL of the query. 107 // |url| -- the URL of the query.
108 // |results| -- the structure to fill with proxy resolve results. 108 // |results| -- the structure to fill with proxy resolve results.
109 Job(SingleThreadedProxyResolver* coordinator, 109 Job(SingleThreadedProxyResolver* coordinator,
110 const GURL& url, 110 const GURL& url,
111 ProxyInfo* results, 111 ProxyInfo* results,
112 CompletionCallback* callback, 112 CompletionCallback* callback,
113 LoadLog* load_log) 113 const BoundNetLog& net_log)
114 : coordinator_(coordinator), 114 : coordinator_(coordinator),
115 callback_(callback), 115 callback_(callback),
116 results_(results), 116 results_(results),
117 load_log_(load_log), 117 net_log_(net_log),
118 url_(url), 118 url_(url),
119 is_started_(false), 119 is_started_(false),
120 origin_loop_(MessageLoop::current()) { 120 origin_loop_(MessageLoop::current()) {
121 DCHECK(callback); 121 DCHECK(callback);
122 } 122 }
123 123
124 // Start the resolve proxy request on the worker thread. 124 // Start the resolve proxy request on the worker thread.
125 void Start() { 125 void Start() {
126 is_started_ = true; 126 is_started_ = true;
127 127
128 size_t load_log_bound = load_log_ ? load_log_->max_num_entries() : 0; 128 size_t load_log_bound = 100;
129 129
130 coordinator_->thread()->message_loop()->PostTask( 130 coordinator_->thread()->message_loop()->PostTask(
131 FROM_HERE, NewRunnableMethod(this, &Job::DoQuery, 131 FROM_HERE, NewRunnableMethod(this, &Job::DoQuery,
132 coordinator_->resolver_.get(), 132 coordinator_->resolver_.get(),
133 load_log_bound)); 133 load_log_bound));
134 } 134 }
135 135
136 bool is_started() const { return is_started_; } 136 bool is_started() const { return is_started_; }
137 137
138 void Cancel() { 138 void Cancel() {
139 // Clear these to inform QueryComplete that it should not try to 139 // Clear these to inform QueryComplete that it should not try to
140 // access them. 140 // access them.
141 coordinator_ = NULL; 141 coordinator_ = NULL;
142 callback_ = NULL; 142 callback_ = NULL;
143 results_ = NULL; 143 results_ = NULL;
144 } 144 }
145 145
146 // Returns true if Cancel() has been called. 146 // Returns true if Cancel() has been called.
147 bool was_cancelled() const { return callback_ == NULL; } 147 bool was_cancelled() const { return callback_ == NULL; }
148 148
149 LoadLog* load_log() { return load_log_; } 149 BoundNetLog* net_log() { return &net_log_; }
150 150
151 private: 151 private:
152 friend class base::RefCountedThreadSafe<SingleThreadedProxyResolver::Job>; 152 friend class base::RefCountedThreadSafe<SingleThreadedProxyResolver::Job>;
153 153
154 ~Job() {} 154 ~Job() {}
155 155
156 // Runs on the worker thread. 156 // Runs on the worker thread.
157 void DoQuery(ProxyResolver* resolver, size_t load_log_bound) { 157 void DoQuery(ProxyResolver* resolver, size_t load_log_bound) {
158 LoadLog* worker_log = NULL; 158 scoped_ptr<CapturingNetLog> worker_log(new CapturingNetLog(load_log_bound));
159 if (load_log_bound > 0) { 159 BoundNetLog bound_worker_log(NetLog::Source(), worker_log.get());
160 worker_log = new LoadLog(load_log_bound);
161 worker_log->AddRef(); // Balanced in QueryComplete.
162 }
163 160
164 int rv = resolver->GetProxyForURL(url_, &results_buf_, NULL, NULL, 161 int rv = resolver->GetProxyForURL(url_, &results_buf_, NULL, NULL,
165 worker_log); 162 bound_worker_log);
166 DCHECK_NE(rv, ERR_IO_PENDING); 163 DCHECK_NE(rv, ERR_IO_PENDING);
167 164
168 origin_loop_->PostTask(FROM_HERE, 165 origin_loop_->PostTask(FROM_HERE,
169 NewRunnableMethod(this, &Job::QueryComplete, rv, worker_log)); 166 NewRunnableMethod(this, &Job::QueryComplete, rv, worker_log.release()));
170 } 167 }
171 168
172 // Runs the completion callback on the origin thread. 169 // Runs the completion callback on the origin thread.
173 void QueryComplete(int result_code, LoadLog* worker_log) { 170 void QueryComplete(int result_code, CapturingNetLog* worker_log) {
174 // Merge the load log that was generated on the worker thread, into the 171 // Merge the load log that was generated on the worker thread, into the
175 // main log. 172 // main log.
176 if (worker_log) { 173 CapturingBoundNetLog bound_worker_log(NetLog::Source(), worker_log);
177 if (load_log_) 174 bound_worker_log.AppendTo(net_log_);
178 load_log_->Append(worker_log);
179 worker_log->Release();
180 }
181 175
182 // The Job may have been cancelled after it was started. 176 // The Job may have been cancelled after it was started.
183 if (!was_cancelled()) { 177 if (!was_cancelled()) {
184 if (result_code >= OK) { // Note: unit-tests use values > 0. 178 if (result_code >= OK) { // Note: unit-tests use values > 0.
185 results_->Use(results_buf_); 179 results_->Use(results_buf_);
186 } 180 }
187 callback_->Run(result_code); 181 callback_->Run(result_code);
188 182
189 // We check for cancellation once again, in case the callback deleted 183 // We check for cancellation once again, in case the callback deleted
190 // the owning ProxyService (whose destructor will in turn cancel us). 184 // the owning ProxyService (whose destructor will in turn cancel us).
191 if (!was_cancelled()) 185 if (!was_cancelled())
192 coordinator_->RemoveFrontOfJobsQueueAndStartNext(this); 186 coordinator_->RemoveFrontOfJobsQueueAndStartNext(this);
193 } 187 }
194 } 188 }
195 189
196 // Must only be used on the "origin" thread. 190 // Must only be used on the "origin" thread.
197 SingleThreadedProxyResolver* coordinator_; 191 SingleThreadedProxyResolver* coordinator_;
198 CompletionCallback* callback_; 192 CompletionCallback* callback_;
199 ProxyInfo* results_; 193 ProxyInfo* results_;
200 scoped_refptr<LoadLog> load_log_; 194 BoundNetLog net_log_;
201 GURL url_; 195 GURL url_;
202 bool is_started_; 196 bool is_started_;
203 197
204 // Usable from within DoQuery on the worker thread. 198 // Usable from within DoQuery on the worker thread.
205 ProxyInfo results_buf_; 199 ProxyInfo results_buf_;
206 MessageLoop* origin_loop_; 200 MessageLoop* origin_loop_;
207 }; 201 };
208 202
209 // SingleThreadedProxyResolver ------------------------------------------------ 203 // SingleThreadedProxyResolver ------------------------------------------------
210 204
(...skipping 15 matching lines...) Expand all
226 outstanding_set_pac_script_task_->Cancel(); 220 outstanding_set_pac_script_task_->Cancel();
227 221
228 // Note that |thread_| is destroyed before |resolver_|. This is important 222 // Note that |thread_| is destroyed before |resolver_|. This is important
229 // since |resolver_| could be running on |thread_|. 223 // since |resolver_| could be running on |thread_|.
230 } 224 }
231 225
232 int SingleThreadedProxyResolver::GetProxyForURL(const GURL& url, 226 int SingleThreadedProxyResolver::GetProxyForURL(const GURL& url,
233 ProxyInfo* results, 227 ProxyInfo* results,
234 CompletionCallback* callback, 228 CompletionCallback* callback,
235 RequestHandle* request, 229 RequestHandle* request,
236 LoadLog* load_log) { 230 const BoundNetLog& net_log) {
237 DCHECK(callback); 231 DCHECK(callback);
238 232
239 scoped_refptr<Job> job = new Job(this, url, results, callback, load_log); 233 scoped_refptr<Job> job = new Job(this, url, results, callback, net_log);
240 bool is_first_job = pending_jobs_.empty(); 234 bool is_first_job = pending_jobs_.empty();
241 pending_jobs_.push_back(job); // Jobs can never finish synchronously. 235 pending_jobs_.push_back(job); // Jobs can never finish synchronously.
242 236
243 if (is_first_job) { 237 if (is_first_job) {
244 // If there is nothing already running, start the job now. 238 // If there is nothing already running, start the job now.
245 EnsureThreadStarted(); 239 EnsureThreadStarted();
246 job->Start(); 240 job->Start();
247 } else { 241 } else {
248 // Otherwise the job will get started eventually by ProcessPendingJobs(). 242 // Otherwise the job will get started eventually by ProcessPendingJobs().
249 LoadLog::BeginEvent( 243 job->net_log()->BeginEvent(NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_TH READ);
250 job->load_log(),
251 LoadLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD);
252 } 244 }
253 245
254 // Completion will be notified through |callback|, unless the caller cancels 246 // Completion will be notified through |callback|, unless the caller cancels
255 // the request using |request|. 247 // the request using |request|.
256 if (request) 248 if (request)
257 *request = reinterpret_cast<RequestHandle>(job.get()); 249 *request = reinterpret_cast<RequestHandle>(job.get());
258 250
259 return ERR_IO_PENDING; 251 return ERR_IO_PENDING;
260 } 252 }
261 253
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 314
323 void SingleThreadedProxyResolver::ProcessPendingJobs() { 315 void SingleThreadedProxyResolver::ProcessPendingJobs() {
324 if (pending_jobs_.empty()) 316 if (pending_jobs_.empty())
325 return; 317 return;
326 318
327 // Get the next job to process (FIFO). 319 // Get the next job to process (FIFO).
328 Job* job = pending_jobs_.front().get(); 320 Job* job = pending_jobs_.front().get();
329 if (job->is_started()) 321 if (job->is_started())
330 return; 322 return;
331 323
332 LoadLog::EndEvent( 324 job->net_log()->EndEvent(
333 job->load_log(), 325 NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD);
334 LoadLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD);
335 326
336 EnsureThreadStarted(); 327 EnsureThreadStarted();
337 job->Start(); 328 job->Start();
338 } 329 }
339 330
340 void SingleThreadedProxyResolver::RemoveFrontOfJobsQueueAndStartNext( 331 void SingleThreadedProxyResolver::RemoveFrontOfJobsQueueAndStartNext(
341 Job* expected_job) { 332 Job* expected_job) {
342 DCHECK_EQ(expected_job, pending_jobs_.front().get()); 333 DCHECK_EQ(expected_job, pending_jobs_.front().get());
343 pending_jobs_.pop_front(); 334 pending_jobs_.pop_front();
344 335
345 // Start next work item. 336 // Start next work item.
346 ProcessPendingJobs(); 337 ProcessPendingJobs();
347 } 338 }
348 339
349 void SingleThreadedProxyResolver::RemoveOutstandingSetPacScriptTask( 340 void SingleThreadedProxyResolver::RemoveOutstandingSetPacScriptTask(
350 SetPacScriptTask* task) { 341 SetPacScriptTask* task) {
351 DCHECK_EQ(outstanding_set_pac_script_task_.get(), task); 342 DCHECK_EQ(outstanding_set_pac_script_task_.get(), task);
352 outstanding_set_pac_script_task_ = NULL; 343 outstanding_set_pac_script_task_ = NULL;
353 } 344 }
354 345
355 } // namespace net 346 } // namespace net
OLDNEW
« no previous file with comments | « net/proxy/single_threaded_proxy_resolver.h ('k') | net/proxy/single_threaded_proxy_resolver_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698