| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/host_resolver.h" | 5 #include "net/base/host_resolver.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <ws2tcpip.h> | 8 #include <ws2tcpip.h> |
| 9 #include <wspiapi.h> // Needed for Win2k compat. | 9 #include <wspiapi.h> // Needed for Win2k compat. |
| 10 #elif defined(OS_POSIX) | 10 #elif defined(OS_POSIX) |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 if (mapper) { | 56 if (mapper) { |
| 57 rv = HostResolverProc(mapper->Map(host), port, out); | 57 rv = HostResolverProc(mapper->Map(host), port, out); |
| 58 } else { | 58 } else { |
| 59 rv = HostResolverProc(host, port, out); | 59 rv = HostResolverProc(host, port, out); |
| 60 } | 60 } |
| 61 return rv; | 61 return rv; |
| 62 } | 62 } |
| 63 | 63 |
| 64 //----------------------------------------------------------------------------- | 64 //----------------------------------------------------------------------------- |
| 65 | 65 |
| 66 class HostResolver::Request | 66 class HostResolver::Request : |
| 67 : public base::RefCountedThreadSafe<HostResolver::Request>, | 67 public base::RefCountedThreadSafe<HostResolver::Request> { |
| 68 public MessageLoop::DestructionObserver { | |
| 69 public: | 68 public: |
| 70 Request(HostResolver* resolver, | 69 Request(HostResolver* resolver, |
| 71 const std::string& host, | 70 const std::string& host, |
| 72 const std::string& port, | 71 const std::string& port, |
| 73 AddressList* addresses, | 72 AddressList* addresses, |
| 74 CompletionCallback* callback) | 73 CompletionCallback* callback) |
| 75 : host_(host), | 74 : host_(host), |
| 76 port_(port), | 75 port_(port), |
| 77 resolver_(resolver), | 76 resolver_(resolver), |
| 78 addresses_(addresses), | 77 addresses_(addresses), |
| 79 callback_(callback), | 78 callback_(callback), |
| 80 origin_loop_(MessageLoop::current()), | 79 origin_loop_(MessageLoop::current()), |
| 81 host_mapper_(host_mapper), | 80 host_mapper_(host_mapper), |
| 82 error_(OK), | 81 error_(OK), |
| 83 results_(NULL) { | 82 results_(NULL) { |
| 84 MessageLoop::current()->AddDestructionObserver(this); | |
| 85 } | 83 } |
| 86 | 84 |
| 87 virtual ~Request() { | 85 ~Request() { |
| 88 if (results_) | 86 if (results_) |
| 89 freeaddrinfo(results_); | 87 freeaddrinfo(results_); |
| 90 } | 88 } |
| 91 | 89 |
| 92 void DoLookup() { | 90 void DoLookup() { |
| 93 // Running on the worker thread | 91 // Running on the worker thread |
| 94 error_ = ResolveAddrInfo(host_mapper_, host_, port_, &results_); | 92 error_ = ResolveAddrInfo(host_mapper_, host_, port_, &results_); |
| 95 | 93 |
| 96 Task* reply = NewRunnableMethod(this, &Request::DoCallback); | 94 Task* reply = NewRunnableMethod(this, &Request::DoCallback); |
| 97 | 95 |
| 98 // The origin loop could go away while we are trying to post to it, so we | 96 // The origin loop could go away while we are trying to post to it, so we |
| 99 // need to call its PostTask method inside a lock. See ~HostResolver. | 97 // need to call its PostTask method inside a lock. See ~HostResolver. |
| 100 { | 98 { |
| 101 AutoLock locked(origin_loop_lock_); | 99 AutoLock locked(origin_loop_lock_); |
| 102 if (origin_loop_) { | 100 if (origin_loop_) { |
| 103 origin_loop_->PostTask(FROM_HERE, reply); | 101 origin_loop_->PostTask(FROM_HERE, reply); |
| 104 reply = NULL; | 102 reply = NULL; |
| 105 } | 103 } |
| 106 } | 104 } |
| 107 | 105 |
| 108 // Does nothing if it got posted. | 106 // Does nothing if it got posted. |
| 109 delete reply; | 107 delete reply; |
| 110 } | 108 } |
| 111 | 109 |
| 112 void DoCallback() { | 110 void DoCallback() { |
| 113 // Running on the origin thread. | 111 // Running on the origin thread. |
| 114 DCHECK(error_ || results_); | 112 DCHECK(error_ || results_); |
| 115 | 113 |
| 116 { | |
| 117 AutoLock locked(origin_loop_lock_); | |
| 118 if (origin_loop_) | |
| 119 origin_loop_->RemoveDestructionObserver(this); | |
| 120 } | |
| 121 | |
| 122 // We may have been cancelled! | 114 // We may have been cancelled! |
| 123 if (!resolver_) | 115 if (!resolver_) |
| 124 return; | 116 return; |
| 125 | 117 |
| 126 if (!error_) { | 118 if (!error_) { |
| 127 addresses_->Adopt(results_); | 119 addresses_->Adopt(results_); |
| 128 results_ = NULL; | 120 results_ = NULL; |
| 129 } | 121 } |
| 130 | 122 |
| 131 // Drop the resolver's reference to us. Do this before running the | 123 // Drop the resolver's reference to us. Do this before running the |
| 132 // callback since the callback might result in the resolver being | 124 // callback since the callback might result in the resolver being |
| 133 // destroyed. | 125 // destroyed. |
| 134 resolver_->request_ = NULL; | 126 resolver_->request_ = NULL; |
| 135 | 127 |
| 136 callback_->Run(error_); | 128 callback_->Run(error_); |
| 137 } | 129 } |
| 138 | 130 |
| 139 void Cancel() { | 131 void Cancel() { |
| 140 resolver_ = NULL; | 132 resolver_ = NULL; |
| 141 | 133 |
| 142 AutoLock locked(origin_loop_lock_); | 134 AutoLock locked(origin_loop_lock_); |
| 143 origin_loop_ = NULL; | 135 origin_loop_ = NULL; |
| 144 } | 136 } |
| 145 | 137 |
| 146 virtual void WillDestroyCurrentMessageLoop() { | |
| 147 AutoLock locked(origin_loop_lock_); | |
| 148 origin_loop_ = NULL; | |
| 149 } | |
| 150 | |
| 151 private: | 138 private: |
| 152 // Set on the origin thread, read on the worker thread. | 139 // Set on the origin thread, read on the worker thread. |
| 153 std::string host_; | 140 std::string host_; |
| 154 std::string port_; | 141 std::string port_; |
| 155 | 142 |
| 156 // Only used on the origin thread (where Resolve was called). | 143 // Only used on the origin thread (where Resolve was called). |
| 157 HostResolver* resolver_; | 144 HostResolver* resolver_; |
| 158 AddressList* addresses_; | 145 AddressList* addresses_; |
| 159 CompletionCallback* callback_; | 146 CompletionCallback* callback_; |
| 160 | 147 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 175 | 162 |
| 176 //----------------------------------------------------------------------------- | 163 //----------------------------------------------------------------------------- |
| 177 | 164 |
| 178 HostResolver::HostResolver() { | 165 HostResolver::HostResolver() { |
| 179 #if defined(OS_WIN) | 166 #if defined(OS_WIN) |
| 180 EnsureWinsockInit(); | 167 EnsureWinsockInit(); |
| 181 #endif | 168 #endif |
| 182 } | 169 } |
| 183 | 170 |
| 184 HostResolver::~HostResolver() { | 171 HostResolver::~HostResolver() { |
| 185 if (request_) { | 172 if (request_) |
| 186 request_->Cancel(); | 173 request_->Cancel(); |
| 187 MessageLoop::current()->RemoveDestructionObserver(request_.get()); | |
| 188 } | |
| 189 } | 174 } |
| 190 | 175 |
| 191 int HostResolver::Resolve(const std::string& hostname, int port, | 176 int HostResolver::Resolve(const std::string& hostname, int port, |
| 192 AddressList* addresses, | 177 AddressList* addresses, |
| 193 CompletionCallback* callback) { | 178 CompletionCallback* callback) { |
| 194 DCHECK(!request_) << "resolver already in use"; | 179 DCHECK(!request_) << "resolver already in use"; |
| 195 | 180 |
| 196 const std::string& port_str = IntToString(port); | 181 const std::string& port_str = IntToString(port); |
| 197 | 182 |
| 198 // Do a synchronous resolution. | 183 // Do a synchronous resolution. |
| 199 if (!callback) { | 184 if (!callback) { |
| 200 struct addrinfo* results; | 185 struct addrinfo* results; |
| 201 int rv = ResolveAddrInfo(host_mapper, hostname, port_str, &results); | 186 int rv = ResolveAddrInfo(host_mapper, hostname, port_str, &results); |
| 202 if (rv == OK) | 187 if (rv == OK) |
| 203 addresses->Adopt(results); | 188 addresses->Adopt(results); |
| 204 return rv; | 189 return rv; |
| 205 } | 190 } |
| 206 | 191 |
| 207 request_ = new Request(this, hostname, port_str, addresses, callback); | 192 request_ = new Request(this, hostname, port_str, addresses, callback); |
| 208 | 193 |
| 209 // Dispatch to worker thread... | 194 // Dispatch to worker thread... |
| 210 if (!WorkerPool::PostTask(FROM_HERE, | 195 if (!WorkerPool::PostTask(FROM_HERE, |
| 211 NewRunnableMethod(request_.get(), &Request::DoLookup), true)) { | 196 NewRunnableMethod(request_.get(), &Request::DoLookup), true)) { |
| 212 NOTREACHED(); | 197 NOTREACHED(); |
| 213 MessageLoop::current()->RemoveDestructionObserver(request_.get()); | |
| 214 request_ = NULL; | 198 request_ = NULL; |
| 215 return ERR_FAILED; | 199 return ERR_FAILED; |
| 216 } | 200 } |
| 217 | 201 |
| 218 return ERR_IO_PENDING; | 202 return ERR_IO_PENDING; |
| 219 } | 203 } |
| 220 | 204 |
| 221 } // namespace net | 205 } // namespace net |
| OLD | NEW |