diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-06 18:10:54 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-06 18:10:54 +0000 |
commit | 517fd6dc47748030a321ceb54f0d7f8539c6d45e (patch) | |
tree | e6bf879c0af08367d90d8949de29cc29bb2031f1 /net | |
parent | 34ebfbc2573c29e3c49a4ed8689b6daccb19471b (diff) | |
download | chromium_src-517fd6dc47748030a321ceb54f0d7f8539c6d45e.zip chromium_src-517fd6dc47748030a321ceb54f0d7f8539c6d45e.tar.gz chromium_src-517fd6dc47748030a321ceb54f0d7f8539c6d45e.tar.bz2 |
Fix HostResolver crash when MessageLoop is destroyed during
asynchronous resolution.
This should hopefully fix reliability failures introduced in r9312.
TBR=darin
Review URL: http://codereview.chromium.org/19534
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9317 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/host_resolver.cc | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/net/base/host_resolver.cc b/net/base/host_resolver.cc index d5d97e7..7480fdb 100644 --- a/net/base/host_resolver.cc +++ b/net/base/host_resolver.cc @@ -63,8 +63,9 @@ static int ResolveAddrInfo(HostMapper* mapper, const std::string& host, //----------------------------------------------------------------------------- -class HostResolver::Request : - public base::RefCountedThreadSafe<HostResolver::Request> { +class HostResolver::Request + : public base::RefCountedThreadSafe<HostResolver::Request>, + public MessageLoop::DestructionObserver { public: Request(HostResolver* resolver, const std::string& host, @@ -80,9 +81,10 @@ class HostResolver::Request : host_mapper_(host_mapper), error_(OK), results_(NULL) { + MessageLoop::current()->AddDestructionObserver(this); } - ~Request() { + virtual ~Request() { if (results_) freeaddrinfo(results_); } @@ -111,6 +113,12 @@ class HostResolver::Request : // Running on the origin thread. DCHECK(error_ || results_); + { + AutoLock locked(origin_loop_lock_); + if (origin_loop_) + origin_loop_->RemoveDestructionObserver(this); + } + // We may have been cancelled! if (!resolver_) return; @@ -135,6 +143,11 @@ class HostResolver::Request : origin_loop_ = NULL; } + virtual void WillDestroyCurrentMessageLoop() { + AutoLock locked(origin_loop_lock_); + origin_loop_ = NULL; + } + private: // Set on the origin thread, read on the worker thread. std::string host_; @@ -169,8 +182,10 @@ HostResolver::HostResolver() { } HostResolver::~HostResolver() { - if (request_) + if (request_) { request_->Cancel(); + MessageLoop::current()->RemoveDestructionObserver(request_.get()); + } } int HostResolver::Resolve(const std::string& hostname, int port, @@ -195,6 +210,7 @@ int HostResolver::Resolve(const std::string& hostname, int port, if (!WorkerPool::PostTask(FROM_HERE, NewRunnableMethod(request_.get(), &Request::DoLookup), true)) { NOTREACHED(); + MessageLoop::current()->RemoveDestructionObserver(request_.get()); request_ = NULL; return ERR_FAILED; } |