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