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

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

Issue 160510: Better match IE's proxy settings.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix merge conflict Created 11 years, 4 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/net_errors.h" 8 #include "net/base/net_errors.h"
9 #include "net/proxy/proxy_info.h" 9 #include "net/proxy/proxy_info.h"
10 10
11 namespace net { 11 namespace net {
12 12
13 // Runs on the worker thread to call ProxyResolver::SetPacScriptByUrl or 13 // SingleThreadedProxyResolver::SetPacScriptTask ------------------------------
14 // ProxyResolver::SetPacScriptByData. 14
15 // TODO(eroman): the lifetime of this task is ill-defined; |resolver_| must 15 // Runs on the worker thread to call ProxyResolver::SetPacScript.
16 // be valid when the task eventually is run. Make this task cancellable. 16 class SingleThreadedProxyResolver::SetPacScriptTask
17 class SetPacScriptTask : public Task { 17 : public base::RefCountedThreadSafe<
18 SingleThreadedProxyResolver::SetPacScriptTask> {
18 public: 19 public:
19 SetPacScriptTask(ProxyResolver* resolver, 20 SetPacScriptTask(SingleThreadedProxyResolver* coordinator,
20 const GURL& pac_url, 21 const GURL& pac_url,
21 const std::string& bytes) 22 const std::string& pac_bytes,
22 : resolver_(resolver), pac_url_(pac_url), bytes_(bytes) {} 23 CompletionCallback* callback)
23 24 : coordinator_(coordinator),
24 virtual void Run() { 25 callback_(callback),
25 if (resolver_->expects_pac_bytes()) 26 pac_bytes_(pac_bytes),
26 resolver_->SetPacScriptByData(bytes_); 27 pac_url_(pac_url),
27 else 28 origin_loop_(MessageLoop::current()) {
28 resolver_->SetPacScriptByUrl(pac_url_); 29 DCHECK(callback);
29 } 30 }
30 31
32 // Start the SetPacScript request on the worker thread.
33 void Start() {
34 // TODO(eroman): Are these manual AddRef / Release necessary?
35 AddRef(); // balanced in RequestComplete
36
37 coordinator_->thread()->message_loop()->PostTask(
38 FROM_HERE, NewRunnableMethod(this, &SetPacScriptTask::DoRequest,
39 coordinator_->resolver_.get()));
40 }
41
42 void Cancel() {
43 // Clear these to inform RequestComplete that it should not try to
44 // access them.
45 coordinator_ = NULL;
46 callback_ = NULL;
47 }
48
49 // Returns true if Cancel() has been called.
50 bool was_cancelled() const { return callback_ == NULL; }
51
31 private: 52 private:
32 ProxyResolver* resolver_; 53 // Runs on the worker thread.
54 void DoRequest(ProxyResolver* resolver) {
55 int rv = resolver->expects_pac_bytes() ?
56 resolver->SetPacScriptByData(pac_bytes_, NULL) :
57 resolver->SetPacScriptByUrl(pac_url_, NULL);
58
59 DCHECK_NE(rv, ERR_IO_PENDING);
60 origin_loop_->PostTask(FROM_HERE,
61 NewRunnableMethod(this, &SetPacScriptTask::RequestComplete, rv));
62 }
63
64 // Runs the completion callback on the origin thread.
65 void RequestComplete(int result_code) {
66 // The task may have been cancelled after it was started.
67 if (!was_cancelled()) {
68 CompletionCallback* callback = callback_;
69 coordinator_->RemoveOutstandingSetPacScriptTask(this);
70 callback->Run(result_code);
71 }
72
73 Release(); // Balances the AddRef in Start.
74 }
75
76 // Must only be used on the "origin" thread.
77 SingleThreadedProxyResolver* coordinator_;
78 CompletionCallback* callback_;
79 std::string pac_bytes_;
33 GURL pac_url_; 80 GURL pac_url_;
34 std::string bytes_; 81
82 // Usable from within DoQuery on the worker thread.
83 MessageLoop* origin_loop_;
35 }; 84 };
36 85
37 // SingleThreadedProxyResolver::Job ------------------------------------------- 86 // SingleThreadedProxyResolver::Job -------------------------------------------
38 87
39 class SingleThreadedProxyResolver::Job 88 class SingleThreadedProxyResolver::Job
40 : public base::RefCountedThreadSafe<SingleThreadedProxyResolver::Job> { 89 : public base::RefCountedThreadSafe<SingleThreadedProxyResolver::Job> {
41 public: 90 public:
42 // |coordinator| -- the SingleThreadedProxyResolver that owns this job. 91 // |coordinator| -- the SingleThreadedProxyResolver that owns this job.
43 // |url| -- the URL of the query. 92 // |url| -- the URL of the query.
44 // |results| -- the structure to fill with proxy resolve results. 93 // |results| -- the structure to fill with proxy resolve results.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 results_->Use(results_buf_); 144 results_->Use(results_buf_);
96 } 145 }
97 callback_->Run(result_code); 146 callback_->Run(result_code);
98 147
99 // We check for cancellation once again, in case the callback deleted 148 // We check for cancellation once again, in case the callback deleted
100 // the owning ProxyService (whose destructor will in turn cancel us). 149 // the owning ProxyService (whose destructor will in turn cancel us).
101 if (!was_cancelled()) 150 if (!was_cancelled())
102 coordinator_->RemoveFrontOfJobsQueueAndStartNext(this); 151 coordinator_->RemoveFrontOfJobsQueueAndStartNext(this);
103 } 152 }
104 153
105 Release(); // balances the AddRef in Query. we may get deleted after 154 Release(); // Balances the AddRef in Start. We may get deleted after
106 // we return. 155 // we return.
107 } 156 }
108 157
109 // Must only be used on the "origin" thread. 158 // Must only be used on the "origin" thread.
110 SingleThreadedProxyResolver* coordinator_; 159 SingleThreadedProxyResolver* coordinator_;
111 CompletionCallback* callback_; 160 CompletionCallback* callback_;
112 ProxyInfo* results_; 161 ProxyInfo* results_;
113 GURL url_; 162 GURL url_;
114 bool is_started_; 163 bool is_started_;
115 164
(...skipping 11 matching lines...) Expand all
127 } 176 }
128 177
129 SingleThreadedProxyResolver::~SingleThreadedProxyResolver() { 178 SingleThreadedProxyResolver::~SingleThreadedProxyResolver() {
130 // Cancel the inprogress job (if any), and free the rest. 179 // Cancel the inprogress job (if any), and free the rest.
131 for (PendingJobsQueue::iterator it = pending_jobs_.begin(); 180 for (PendingJobsQueue::iterator it = pending_jobs_.begin();
132 it != pending_jobs_.end(); 181 it != pending_jobs_.end();
133 ++it) { 182 ++it) {
134 (*it)->Cancel(); 183 (*it)->Cancel();
135 } 184 }
136 185
186 if (outstanding_set_pac_script_task_)
187 outstanding_set_pac_script_task_->Cancel();
188
137 // Note that |thread_| is destroyed before |resolver_|. This is important 189 // Note that |thread_| is destroyed before |resolver_|. This is important
138 // since |resolver_| could be running on |thread_|. 190 // since |resolver_| could be running on |thread_|.
139 } 191 }
140 192
141 int SingleThreadedProxyResolver::GetProxyForURL(const GURL& url, 193 int SingleThreadedProxyResolver::GetProxyForURL(const GURL& url,
142 ProxyInfo* results, 194 ProxyInfo* results,
143 CompletionCallback* callback, 195 CompletionCallback* callback,
144 RequestHandle* request) { 196 RequestHandle* request) {
145 DCHECK(callback); 197 DCHECK(callback);
146 198
(...skipping 28 matching lines...) Expand all
175 return; 227 return;
176 } 228 }
177 229
178 // Otherwise just delete the job from the queue. 230 // Otherwise just delete the job from the queue.
179 PendingJobsQueue::iterator it = std::find( 231 PendingJobsQueue::iterator it = std::find(
180 pending_jobs_.begin(), pending_jobs_.end(), job); 232 pending_jobs_.begin(), pending_jobs_.end(), job);
181 DCHECK(it != pending_jobs_.end()); 233 DCHECK(it != pending_jobs_.end());
182 pending_jobs_.erase(it); 234 pending_jobs_.erase(it);
183 } 235 }
184 236
185 void SingleThreadedProxyResolver::SetPacScriptByUrlInternal( 237 void SingleThreadedProxyResolver::CancelSetPacScript() {
186 const GURL& pac_url) { 238 DCHECK(outstanding_set_pac_script_task_);
187 SetPacScriptHelper(pac_url, std::string()); 239 outstanding_set_pac_script_task_->Cancel();
240 outstanding_set_pac_script_task_ = NULL;
188 } 241 }
189 242
190 void SingleThreadedProxyResolver::SetPacScriptByDataInternal( 243 int SingleThreadedProxyResolver::SetPacScript(
191 const std::string& bytes) { 244 const GURL& pac_url,
192 SetPacScriptHelper(GURL(), bytes); 245 const std::string& pac_bytes,
193 } 246 CompletionCallback* callback) {
247 EnsureThreadStarted();
248 DCHECK(!outstanding_set_pac_script_task_);
194 249
195 void SingleThreadedProxyResolver::SetPacScriptHelper(const GURL& pac_url, 250 SetPacScriptTask* task = new SetPacScriptTask(
196 const std::string& bytes) { 251 this, pac_url, pac_bytes, callback);
197 EnsureThreadStarted(); 252 outstanding_set_pac_script_task_ = task;
198 thread()->message_loop()->PostTask( 253 task->Start();
199 FROM_HERE, new SetPacScriptTask(resolver(), pac_url, bytes)); 254 return ERR_IO_PENDING;
200 } 255 }
201 256
202 void SingleThreadedProxyResolver::EnsureThreadStarted() { 257 void SingleThreadedProxyResolver::EnsureThreadStarted() {
203 if (!thread_.get()) { 258 if (!thread_.get()) {
204 thread_.reset(new base::Thread("pac-thread")); 259 thread_.reset(new base::Thread("pac-thread"));
205 thread_->Start(); 260 thread_->Start();
206 } 261 }
207 } 262 }
208 263
209 void SingleThreadedProxyResolver::ProcessPendingJobs() { 264 void SingleThreadedProxyResolver::ProcessPendingJobs() {
(...skipping 11 matching lines...) Expand all
221 276
222 void SingleThreadedProxyResolver::RemoveFrontOfJobsQueueAndStartNext( 277 void SingleThreadedProxyResolver::RemoveFrontOfJobsQueueAndStartNext(
223 Job* expected_job) { 278 Job* expected_job) {
224 DCHECK_EQ(expected_job, pending_jobs_.front().get()); 279 DCHECK_EQ(expected_job, pending_jobs_.front().get());
225 pending_jobs_.pop_front(); 280 pending_jobs_.pop_front();
226 281
227 // Start next work item. 282 // Start next work item.
228 ProcessPendingJobs(); 283 ProcessPendingJobs();
229 } 284 }
230 285
286 void SingleThreadedProxyResolver::RemoveOutstandingSetPacScriptTask(
287 SetPacScriptTask* task) {
288 DCHECK_EQ(outstanding_set_pac_script_task_.get(), task);
289 outstanding_set_pac_script_task_ = NULL;
290 }
291
231 } // namespace net 292 } // 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