| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/base/dnsrr_resolver.h" | 5 #include "net/base/dnsrr_resolver.h" |
| 6 | 6 |
| 7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
| 8 #include <resolv.h> | 8 #include <resolv.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| 11 #include "base/lock.h" | |
| 12 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 13 #include "base/scoped_ptr.h" | 12 #include "base/scoped_ptr.h" |
| 14 #include "base/singleton.h" | 13 #include "base/singleton.h" |
| 15 #include "base/stl_util-inl.h" | 14 #include "base/stl_util-inl.h" |
| 16 #include "base/string_piece.h" | 15 #include "base/string_piece.h" |
| 16 #include "base/synchronization/lock.h" |
| 17 #include "base/task.h" | 17 #include "base/task.h" |
| 18 #include "base/threading/worker_pool.h" | 18 #include "base/threading/worker_pool.h" |
| 19 #include "net/base/dns_reload_timer.h" | 19 #include "net/base/dns_reload_timer.h" |
| 20 #include "net/base/dns_util.h" | 20 #include "net/base/dns_util.h" |
| 21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 22 | 22 |
| 23 // Life of a query: | 23 // Life of a query: |
| 24 // | 24 // |
| 25 // DnsRRResolver RRResolverJob RRResolverWorker ... Handle | 25 // DnsRRResolver RRResolverJob RRResolverWorker ... Handle |
| 26 // | (origin loop) (worker loop) | 26 // | (origin loop) (worker loop) |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 | 137 |
| 138 return base::WorkerPool::PostTask( | 138 return base::WorkerPool::PostTask( |
| 139 FROM_HERE, NewRunnableMethod(this, &RRResolverWorker::Run), | 139 FROM_HERE, NewRunnableMethod(this, &RRResolverWorker::Run), |
| 140 true /* task is slow */); | 140 true /* task is slow */); |
| 141 } | 141 } |
| 142 | 142 |
| 143 // Cancel is called from the origin loop when the DnsRRResolver is getting | 143 // Cancel is called from the origin loop when the DnsRRResolver is getting |
| 144 // deleted. | 144 // deleted. |
| 145 void Cancel() { | 145 void Cancel() { |
| 146 DCHECK_EQ(MessageLoop::current(), origin_loop_); | 146 DCHECK_EQ(MessageLoop::current(), origin_loop_); |
| 147 AutoLock locked(lock_); | 147 base::AutoLock locked(lock_); |
| 148 canceled_ = true; | 148 canceled_ = true; |
| 149 } | 149 } |
| 150 | 150 |
| 151 private: | 151 private: |
| 152 | 152 |
| 153 #if defined(OS_POSIX) | 153 #if defined(OS_POSIX) |
| 154 | 154 |
| 155 void Run() { | 155 void Run() { |
| 156 // Runs on a worker thread. | 156 // Runs on a worker thread. |
| 157 | 157 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 } | 264 } |
| 265 | 265 |
| 266 // DoReply runs on the origin thread. | 266 // DoReply runs on the origin thread. |
| 267 void DoReply() { | 267 void DoReply() { |
| 268 DCHECK_EQ(MessageLoop::current(), origin_loop_); | 268 DCHECK_EQ(MessageLoop::current(), origin_loop_); |
| 269 { | 269 { |
| 270 // We lock here because the worker thread could still be in Finished, | 270 // We lock here because the worker thread could still be in Finished, |
| 271 // after the PostTask, but before unlocking |lock_|. If we do not lock in | 271 // after the PostTask, but before unlocking |lock_|. If we do not lock in |
| 272 // this case, we will end up deleting a locked Lock, which can lead to | 272 // this case, we will end up deleting a locked Lock, which can lead to |
| 273 // memory leaks or worse errors. | 273 // memory leaks or worse errors. |
| 274 AutoLock locked(lock_); | 274 base::AutoLock locked(lock_); |
| 275 if (!canceled_) | 275 if (!canceled_) |
| 276 dnsrr_resolver_->HandleResult(name_, rrtype_, result_, response_); | 276 dnsrr_resolver_->HandleResult(name_, rrtype_, result_, response_); |
| 277 } | 277 } |
| 278 delete this; | 278 delete this; |
| 279 } | 279 } |
| 280 | 280 |
| 281 void Finish() { | 281 void Finish() { |
| 282 // Runs on the worker thread. | 282 // Runs on the worker thread. |
| 283 // We assume that the origin loop outlives the DnsRRResolver. If the | 283 // We assume that the origin loop outlives the DnsRRResolver. If the |
| 284 // DnsRRResolver is deleted, it will call Cancel on us. If it does so | 284 // DnsRRResolver is deleted, it will call Cancel on us. If it does so |
| 285 // before the Acquire, we'll delete ourselves and return. If it's trying to | 285 // before the Acquire, we'll delete ourselves and return. If it's trying to |
| 286 // do so concurrently, then it'll block on the lock and we'll call PostTask | 286 // do so concurrently, then it'll block on the lock and we'll call PostTask |
| 287 // while the DnsRRResolver (and therefore the MessageLoop) is still alive. | 287 // while the DnsRRResolver (and therefore the MessageLoop) is still alive. |
| 288 // If it does so after this function, we assume that the MessageLoop will | 288 // If it does so after this function, we assume that the MessageLoop will |
| 289 // process pending tasks. In which case we'll notice the |canceled_| flag | 289 // process pending tasks. In which case we'll notice the |canceled_| flag |
| 290 // in DoReply. | 290 // in DoReply. |
| 291 | 291 |
| 292 bool canceled; | 292 bool canceled; |
| 293 { | 293 { |
| 294 AutoLock locked(lock_); | 294 base::AutoLock locked(lock_); |
| 295 canceled = canceled_; | 295 canceled = canceled_; |
| 296 if (!canceled) { | 296 if (!canceled) { |
| 297 origin_loop_->PostTask( | 297 origin_loop_->PostTask( |
| 298 FROM_HERE, NewRunnableMethod(this, &RRResolverWorker::DoReply)); | 298 FROM_HERE, NewRunnableMethod(this, &RRResolverWorker::DoReply)); |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 | 301 |
| 302 if (canceled) | 302 if (canceled) |
| 303 delete this; | 303 delete this; |
| 304 } | 304 } |
| 305 | 305 |
| 306 const std::string name_; | 306 const std::string name_; |
| 307 const uint16 rrtype_; | 307 const uint16 rrtype_; |
| 308 const uint16 flags_; | 308 const uint16 flags_; |
| 309 MessageLoop* const origin_loop_; | 309 MessageLoop* const origin_loop_; |
| 310 DnsRRResolver* const dnsrr_resolver_; | 310 DnsRRResolver* const dnsrr_resolver_; |
| 311 | 311 |
| 312 Lock lock_; | 312 base::Lock lock_; |
| 313 bool canceled_; | 313 bool canceled_; |
| 314 | 314 |
| 315 int result_; | 315 int result_; |
| 316 RRResponse response_; | 316 RRResponse response_; |
| 317 | 317 |
| 318 DISALLOW_COPY_AND_ASSIGN(RRResolverWorker); | 318 DISALLOW_COPY_AND_ASSIGN(RRResolverWorker); |
| 319 }; | 319 }; |
| 320 | 320 |
| 321 | 321 |
| 322 // A Buffer is used for walking over a DNS packet. | 322 // A Buffer is used for walking over a DNS packet. |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 inflight_.erase(j); | 727 inflight_.erase(j); |
| 728 | 728 |
| 729 job->HandleResult(result, response); | 729 job->HandleResult(result, response); |
| 730 delete job; | 730 delete job; |
| 731 } | 731 } |
| 732 | 732 |
| 733 } // namespace net | 733 } // namespace net |
| 734 | 734 |
| 735 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverHandle); | 735 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverHandle); |
| 736 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverWorker); | 736 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverWorker); |
| OLD | NEW |