OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/udp/udp_socket_libevent.h" | 5 #include "net/udp/udp_socket_libevent.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <netdb.h> | 9 #include <netdb.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 30 matching lines...) Expand all Loading... |
41 const net::NetLog::Source& source) | 41 const net::NetLog::Source& source) |
42 : socket_(kInvalidSocket), | 42 : socket_(kInvalidSocket), |
43 bind_type_(bind_type), | 43 bind_type_(bind_type), |
44 rand_int_cb_(rand_int_cb), | 44 rand_int_cb_(rand_int_cb), |
45 read_watcher_(this), | 45 read_watcher_(this), |
46 write_watcher_(this), | 46 write_watcher_(this), |
47 read_buf_len_(0), | 47 read_buf_len_(0), |
48 recv_from_address_(NULL), | 48 recv_from_address_(NULL), |
49 write_buf_len_(0), | 49 write_buf_len_(0), |
50 old_read_callback_(NULL), | 50 old_read_callback_(NULL), |
51 old_write_callback_(NULL), | 51 write_callback_(NULL), |
52 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 52 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
53 scoped_refptr<NetLog::EventParameters> params; | 53 scoped_refptr<NetLog::EventParameters> params; |
54 if (source.is_valid()) | 54 if (source.is_valid()) |
55 params = new NetLogSourceParameter("source_dependency", source); | 55 params = new NetLogSourceParameter("source_dependency", source); |
56 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 56 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
57 if (bind_type == DatagramSocket::RANDOM_BIND) | 57 if (bind_type == DatagramSocket::RANDOM_BIND) |
58 DCHECK(!rand_int_cb.is_null()); | 58 DCHECK(!rand_int_cb.is_null()); |
59 } | 59 } |
60 | 60 |
61 UDPSocketLibevent::~UDPSocketLibevent() { | 61 UDPSocketLibevent::~UDPSocketLibevent() { |
62 Close(); | 62 Close(); |
63 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 63 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); |
64 } | 64 } |
65 | 65 |
66 void UDPSocketLibevent::Close() { | 66 void UDPSocketLibevent::Close() { |
67 DCHECK(CalledOnValidThread()); | 67 DCHECK(CalledOnValidThread()); |
68 | 68 |
69 if (!is_connected()) | 69 if (!is_connected()) |
70 return; | 70 return; |
71 | 71 |
72 // Zero out any pending read/write callback state. | 72 // Zero out any pending read/write callback state. |
73 read_buf_ = NULL; | 73 read_buf_ = NULL; |
74 read_buf_len_ = 0; | 74 read_buf_len_ = 0; |
75 old_read_callback_ = NULL; | 75 old_read_callback_ = NULL; |
76 read_callback_.Reset(); | 76 read_callback_.Reset(); |
77 recv_from_address_ = NULL; | 77 recv_from_address_ = NULL; |
78 write_buf_ = NULL; | 78 write_buf_ = NULL; |
79 write_buf_len_ = 0; | 79 write_buf_len_ = 0; |
80 old_write_callback_ = NULL; | 80 write_callback_ = NULL; |
81 write_callback_.Reset(); | |
82 send_to_address_.reset(); | 81 send_to_address_.reset(); |
83 | 82 |
84 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 83 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
85 DCHECK(ok); | 84 DCHECK(ok); |
86 ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 85 ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
87 DCHECK(ok); | 86 DCHECK(ok); |
88 | 87 |
89 if (HANDLE_EINTR(close(socket_)) < 0) | 88 if (HANDLE_EINTR(close(socket_)) < 0) |
90 PLOG(ERROR) << "close"; | 89 PLOG(ERROR) << "close"; |
91 | 90 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 recv_from_address_ = address; | 205 recv_from_address_ = address; |
207 read_callback_ = callback; | 206 read_callback_ = callback; |
208 return ERR_IO_PENDING; | 207 return ERR_IO_PENDING; |
209 } | 208 } |
210 | 209 |
211 int UDPSocketLibevent::Write(IOBuffer* buf, | 210 int UDPSocketLibevent::Write(IOBuffer* buf, |
212 int buf_len, | 211 int buf_len, |
213 OldCompletionCallback* callback) { | 212 OldCompletionCallback* callback) { |
214 return SendToOrWrite(buf, buf_len, NULL, callback); | 213 return SendToOrWrite(buf, buf_len, NULL, callback); |
215 } | 214 } |
216 int UDPSocketLibevent::Write(IOBuffer* buf, | |
217 int buf_len, | |
218 const CompletionCallback& callback) { | |
219 return SendToOrWrite(buf, buf_len, NULL, callback); | |
220 } | |
221 | 215 |
222 int UDPSocketLibevent::SendTo(IOBuffer* buf, | 216 int UDPSocketLibevent::SendTo(IOBuffer* buf, |
223 int buf_len, | 217 int buf_len, |
224 const IPEndPoint& address, | 218 const IPEndPoint& address, |
225 OldCompletionCallback* callback) { | 219 OldCompletionCallback* callback) { |
226 return SendToOrWrite(buf, buf_len, &address, callback); | 220 return SendToOrWrite(buf, buf_len, &address, callback); |
227 } | 221 } |
228 | 222 |
229 int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf, | 223 int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf, |
230 int buf_len, | 224 int buf_len, |
231 const IPEndPoint* address, | 225 const IPEndPoint* address, |
232 OldCompletionCallback* callback) { | 226 OldCompletionCallback* callback) { |
233 DCHECK(CalledOnValidThread()); | 227 DCHECK(CalledOnValidThread()); |
234 DCHECK_NE(kInvalidSocket, socket_); | 228 DCHECK_NE(kInvalidSocket, socket_); |
235 DCHECK(!old_write_callback_ && write_callback_.is_null()); | 229 DCHECK(!write_callback_); |
236 DCHECK(callback); // Synchronous operation not supported | 230 DCHECK(callback); // Synchronous operation not supported |
237 DCHECK_GT(buf_len, 0); | 231 DCHECK_GT(buf_len, 0); |
238 | 232 |
239 int result = InternalSendTo(buf, buf_len, address); | 233 int result = InternalSendTo(buf, buf_len, address); |
240 if (result != ERR_IO_PENDING) | 234 if (result != ERR_IO_PENDING) |
241 return result; | 235 return result; |
242 | 236 |
243 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 237 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
244 socket_, true, MessageLoopForIO::WATCH_WRITE, | 238 socket_, true, MessageLoopForIO::WATCH_WRITE, |
245 &write_socket_watcher_, &write_watcher_)) { | 239 &write_socket_watcher_, &write_watcher_)) { |
246 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; | 240 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; |
247 int result = MapSystemError(errno); | 241 int result = MapSystemError(errno); |
248 LogWrite(result, NULL, NULL); | 242 LogWrite(result, NULL, NULL); |
249 return result; | 243 return result; |
250 } | 244 } |
251 | 245 |
252 write_buf_ = buf; | 246 write_buf_ = buf; |
253 write_buf_len_ = buf_len; | 247 write_buf_len_ = buf_len; |
254 DCHECK(!send_to_address_.get()); | 248 DCHECK(!send_to_address_.get()); |
255 if (address) { | 249 if (address) { |
256 send_to_address_.reset(new IPEndPoint(*address)); | 250 send_to_address_.reset(new IPEndPoint(*address)); |
257 } | 251 } |
258 old_write_callback_ = callback; | |
259 return ERR_IO_PENDING; | |
260 } | |
261 int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf, | |
262 int buf_len, | |
263 const IPEndPoint* address, | |
264 const CompletionCallback& callback) { | |
265 DCHECK(CalledOnValidThread()); | |
266 DCHECK_NE(kInvalidSocket, socket_); | |
267 DCHECK(!old_write_callback_ && write_callback_.is_null()); | |
268 DCHECK(!callback.is_null()); // Synchronous operation not supported | |
269 DCHECK_GT(buf_len, 0); | |
270 | |
271 int result = InternalSendTo(buf, buf_len, address); | |
272 if (result != ERR_IO_PENDING) | |
273 return result; | |
274 | |
275 if (!MessageLoopForIO::current()->WatchFileDescriptor( | |
276 socket_, true, MessageLoopForIO::WATCH_WRITE, | |
277 &write_socket_watcher_, &write_watcher_)) { | |
278 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; | |
279 int result = MapSystemError(errno); | |
280 LogWrite(result, NULL, NULL); | |
281 return result; | |
282 } | |
283 | |
284 write_buf_ = buf; | |
285 write_buf_len_ = buf_len; | |
286 DCHECK(!send_to_address_.get()); | |
287 if (address) { | |
288 send_to_address_.reset(new IPEndPoint(*address)); | |
289 } | |
290 write_callback_ = callback; | 252 write_callback_ = callback; |
291 return ERR_IO_PENDING; | 253 return ERR_IO_PENDING; |
292 } | 254 } |
293 | 255 |
294 int UDPSocketLibevent::Connect(const IPEndPoint& address) { | 256 int UDPSocketLibevent::Connect(const IPEndPoint& address) { |
295 net_log_.BeginEvent( | 257 net_log_.BeginEvent( |
296 NetLog::TYPE_UDP_CONNECT, | 258 NetLog::TYPE_UDP_CONNECT, |
297 make_scoped_refptr(new NetLogStringParameter("address", | 259 make_scoped_refptr(new NetLogStringParameter("address", |
298 address.ToString()))); | 260 address.ToString()))); |
299 int rv = InternalConnect(address); | 261 int rv = InternalConnect(address); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 c->Run(rv); | 332 c->Run(rv); |
371 } else { | 333 } else { |
372 CompletionCallback c = read_callback_; | 334 CompletionCallback c = read_callback_; |
373 read_callback_.Reset(); | 335 read_callback_.Reset(); |
374 c.Run(rv); | 336 c.Run(rv); |
375 } | 337 } |
376 } | 338 } |
377 | 339 |
378 void UDPSocketLibevent::DoWriteCallback(int rv) { | 340 void UDPSocketLibevent::DoWriteCallback(int rv) { |
379 DCHECK_NE(rv, ERR_IO_PENDING); | 341 DCHECK_NE(rv, ERR_IO_PENDING); |
380 DCHECK(old_write_callback_ || !write_callback_.is_null()); | 342 DCHECK(write_callback_); |
381 | 343 |
382 // since Run may result in Write being called, clear write_callback_ up front. | 344 // since Run may result in Write being called, clear write_callback_ up front. |
383 if (old_write_callback_) { | 345 OldCompletionCallback* c = write_callback_; |
384 OldCompletionCallback* c = old_write_callback_; | 346 write_callback_ = NULL; |
385 old_write_callback_ = NULL; | 347 c->Run(rv); |
386 c->Run(rv); | |
387 } else { | |
388 CompletionCallback c = write_callback_; | |
389 write_callback_.Reset(); | |
390 c.Run(rv); | |
391 } | |
392 } | 348 } |
393 | 349 |
394 void UDPSocketLibevent::DidCompleteRead() { | 350 void UDPSocketLibevent::DidCompleteRead() { |
395 int result = InternalRecvFrom(read_buf_, read_buf_len_, recv_from_address_); | 351 int result = InternalRecvFrom(read_buf_, read_buf_len_, recv_from_address_); |
396 if (result != ERR_IO_PENDING) { | 352 if (result != ERR_IO_PENDING) { |
397 read_buf_ = NULL; | 353 read_buf_ = NULL; |
398 read_buf_len_ = 0; | 354 read_buf_len_ = 0; |
399 recv_from_address_ = NULL; | 355 recv_from_address_ = NULL; |
400 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 356 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
401 DCHECK(ok); | 357 DCHECK(ok); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 | 509 |
554 for (int i = 0; i < kBindRetries; ++i) { | 510 for (int i = 0; i < kBindRetries; ++i) { |
555 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 511 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
556 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 512 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
557 return rv; | 513 return rv; |
558 } | 514 } |
559 return DoBind(IPEndPoint(ip, 0)); | 515 return DoBind(IPEndPoint(ip, 0)); |
560 } | 516 } |
561 | 517 |
562 } // namespace net | 518 } // namespace net |
OLD | NEW |