| 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 write_callback_(NULL), | 51 old_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 write_callback_ = NULL; | 80 old_write_callback_ = NULL; |
| 81 write_callback_.Reset(); |
| 81 send_to_address_.reset(); | 82 send_to_address_.reset(); |
| 82 | 83 |
| 83 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 84 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
| 84 DCHECK(ok); | 85 DCHECK(ok); |
| 85 ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 86 ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
| 86 DCHECK(ok); | 87 DCHECK(ok); |
| 87 | 88 |
| 88 if (HANDLE_EINTR(close(socket_)) < 0) | 89 if (HANDLE_EINTR(close(socket_)) < 0) |
| 89 PLOG(ERROR) << "close"; | 90 PLOG(ERROR) << "close"; |
| 90 | 91 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 recv_from_address_ = address; | 206 recv_from_address_ = address; |
| 206 read_callback_ = callback; | 207 read_callback_ = callback; |
| 207 return ERR_IO_PENDING; | 208 return ERR_IO_PENDING; |
| 208 } | 209 } |
| 209 | 210 |
| 210 int UDPSocketLibevent::Write(IOBuffer* buf, | 211 int UDPSocketLibevent::Write(IOBuffer* buf, |
| 211 int buf_len, | 212 int buf_len, |
| 212 OldCompletionCallback* callback) { | 213 OldCompletionCallback* callback) { |
| 213 return SendToOrWrite(buf, buf_len, NULL, callback); | 214 return SendToOrWrite(buf, buf_len, NULL, callback); |
| 214 } | 215 } |
| 216 int UDPSocketLibevent::Write(IOBuffer* buf, |
| 217 int buf_len, |
| 218 const CompletionCallback& callback) { |
| 219 return SendToOrWrite(buf, buf_len, NULL, callback); |
| 220 } |
| 215 | 221 |
| 216 int UDPSocketLibevent::SendTo(IOBuffer* buf, | 222 int UDPSocketLibevent::SendTo(IOBuffer* buf, |
| 217 int buf_len, | 223 int buf_len, |
| 218 const IPEndPoint& address, | 224 const IPEndPoint& address, |
| 219 OldCompletionCallback* callback) { | 225 OldCompletionCallback* callback) { |
| 220 return SendToOrWrite(buf, buf_len, &address, callback); | 226 return SendToOrWrite(buf, buf_len, &address, callback); |
| 221 } | 227 } |
| 222 | 228 |
| 223 int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf, | 229 int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf, |
| 224 int buf_len, | 230 int buf_len, |
| 225 const IPEndPoint* address, | 231 const IPEndPoint* address, |
| 226 OldCompletionCallback* callback) { | 232 OldCompletionCallback* callback) { |
| 227 DCHECK(CalledOnValidThread()); | 233 DCHECK(CalledOnValidThread()); |
| 228 DCHECK_NE(kInvalidSocket, socket_); | 234 DCHECK_NE(kInvalidSocket, socket_); |
| 229 DCHECK(!write_callback_); | 235 DCHECK(!old_write_callback_ && write_callback_.is_null()); |
| 230 DCHECK(callback); // Synchronous operation not supported | 236 DCHECK(callback); // Synchronous operation not supported |
| 231 DCHECK_GT(buf_len, 0); | 237 DCHECK_GT(buf_len, 0); |
| 232 | 238 |
| 233 int result = InternalSendTo(buf, buf_len, address); | 239 int result = InternalSendTo(buf, buf_len, address); |
| 234 if (result != ERR_IO_PENDING) | 240 if (result != ERR_IO_PENDING) |
| 235 return result; | 241 return result; |
| 236 | 242 |
| 237 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 243 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 238 socket_, true, MessageLoopForIO::WATCH_WRITE, | 244 socket_, true, MessageLoopForIO::WATCH_WRITE, |
| 239 &write_socket_watcher_, &write_watcher_)) { | 245 &write_socket_watcher_, &write_watcher_)) { |
| 240 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; | 246 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; |
| 241 int result = MapSystemError(errno); | 247 int result = MapSystemError(errno); |
| 242 LogWrite(result, NULL, NULL); | 248 LogWrite(result, NULL, NULL); |
| 243 return result; | 249 return result; |
| 244 } | 250 } |
| 245 | 251 |
| 246 write_buf_ = buf; | 252 write_buf_ = buf; |
| 247 write_buf_len_ = buf_len; | 253 write_buf_len_ = buf_len; |
| 248 DCHECK(!send_to_address_.get()); | 254 DCHECK(!send_to_address_.get()); |
| 249 if (address) { | 255 if (address) { |
| 250 send_to_address_.reset(new IPEndPoint(*address)); | 256 send_to_address_.reset(new IPEndPoint(*address)); |
| 251 } | 257 } |
| 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 } |
| 252 write_callback_ = callback; | 290 write_callback_ = callback; |
| 253 return ERR_IO_PENDING; | 291 return ERR_IO_PENDING; |
| 254 } | 292 } |
| 255 | 293 |
| 256 int UDPSocketLibevent::Connect(const IPEndPoint& address) { | 294 int UDPSocketLibevent::Connect(const IPEndPoint& address) { |
| 257 net_log_.BeginEvent( | 295 net_log_.BeginEvent( |
| 258 NetLog::TYPE_UDP_CONNECT, | 296 NetLog::TYPE_UDP_CONNECT, |
| 259 make_scoped_refptr(new NetLogStringParameter("address", | 297 make_scoped_refptr(new NetLogStringParameter("address", |
| 260 address.ToString()))); | 298 address.ToString()))); |
| 261 int rv = InternalConnect(address); | 299 int rv = InternalConnect(address); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 c->Run(rv); | 370 c->Run(rv); |
| 333 } else { | 371 } else { |
| 334 CompletionCallback c = read_callback_; | 372 CompletionCallback c = read_callback_; |
| 335 read_callback_.Reset(); | 373 read_callback_.Reset(); |
| 336 c.Run(rv); | 374 c.Run(rv); |
| 337 } | 375 } |
| 338 } | 376 } |
| 339 | 377 |
| 340 void UDPSocketLibevent::DoWriteCallback(int rv) { | 378 void UDPSocketLibevent::DoWriteCallback(int rv) { |
| 341 DCHECK_NE(rv, ERR_IO_PENDING); | 379 DCHECK_NE(rv, ERR_IO_PENDING); |
| 342 DCHECK(write_callback_); | 380 DCHECK(old_write_callback_ || !write_callback_.is_null()); |
| 343 | 381 |
| 344 // since Run may result in Write being called, clear write_callback_ up front. | 382 // since Run may result in Write being called, clear write_callback_ up front. |
| 345 OldCompletionCallback* c = write_callback_; | 383 if (old_write_callback_) { |
| 346 write_callback_ = NULL; | 384 OldCompletionCallback* c = old_write_callback_; |
| 347 c->Run(rv); | 385 old_write_callback_ = NULL; |
| 386 c->Run(rv); |
| 387 } else { |
| 388 CompletionCallback c = write_callback_; |
| 389 write_callback_.Reset(); |
| 390 c.Run(rv); |
| 391 } |
| 348 } | 392 } |
| 349 | 393 |
| 350 void UDPSocketLibevent::DidCompleteRead() { | 394 void UDPSocketLibevent::DidCompleteRead() { |
| 351 int result = InternalRecvFrom(read_buf_, read_buf_len_, recv_from_address_); | 395 int result = InternalRecvFrom(read_buf_, read_buf_len_, recv_from_address_); |
| 352 if (result != ERR_IO_PENDING) { | 396 if (result != ERR_IO_PENDING) { |
| 353 read_buf_ = NULL; | 397 read_buf_ = NULL; |
| 354 read_buf_len_ = 0; | 398 read_buf_len_ = 0; |
| 355 recv_from_address_ = NULL; | 399 recv_from_address_ = NULL; |
| 356 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 400 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
| 357 DCHECK(ok); | 401 DCHECK(ok); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 | 553 |
| 510 for (int i = 0; i < kBindRetries; ++i) { | 554 for (int i = 0; i < kBindRetries; ++i) { |
| 511 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 555 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
| 512 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 556 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
| 513 return rv; | 557 return rv; |
| 514 } | 558 } |
| 515 return DoBind(IPEndPoint(ip, 0)); | 559 return DoBind(IPEndPoint(ip, 0)); |
| 516 } | 560 } |
| 517 | 561 |
| 518 } // namespace net | 562 } // namespace net |
| OLD | NEW |