Chromium Code Reviews| 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/socket/tcp_client_socket.h" | 5 #include "net/socket/tcp_client_socket.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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 const AddressList& addresses, | 124 const AddressList& addresses, |
| 125 net::NetLog* net_log, | 125 net::NetLog* net_log, |
| 126 const net::NetLog::Source& source) | 126 const net::NetLog::Source& source) |
| 127 : socket_(kInvalidSocket), | 127 : socket_(kInvalidSocket), |
| 128 bound_socket_(kInvalidSocket), | 128 bound_socket_(kInvalidSocket), |
| 129 addresses_(addresses), | 129 addresses_(addresses), |
| 130 current_ai_(NULL), | 130 current_ai_(NULL), |
| 131 read_watcher_(this), | 131 read_watcher_(this), |
| 132 write_watcher_(this), | 132 write_watcher_(this), |
| 133 read_callback_(NULL), | 133 read_callback_(NULL), |
| 134 write_callback_(NULL), | 134 old_write_callback_(NULL), |
| 135 next_connect_state_(CONNECT_STATE_NONE), | 135 next_connect_state_(CONNECT_STATE_NONE), |
| 136 connect_os_error_(0), | 136 connect_os_error_(0), |
| 137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
| 138 previously_disconnected_(false), | 138 previously_disconnected_(false), |
| 139 use_tcp_fastopen_(false), | 139 use_tcp_fastopen_(false), |
| 140 tcp_fastopen_connected_(false), | 140 tcp_fastopen_connected_(false), |
| 141 num_bytes_read_(0) { | 141 num_bytes_read_(0) { |
| 142 scoped_refptr<NetLog::EventParameters> params; | 142 scoped_refptr<NetLog::EventParameters> params; |
| 143 if (source.is_valid()) | 143 if (source.is_valid()) |
| 144 params = new NetLogSourceParameter("source_dependency", source); | 144 params = new NetLogSourceParameter("source_dependency", source); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 | 220 |
| 221 // We will try to connect to each address in addresses_. Start with the | 221 // We will try to connect to each address in addresses_. Start with the |
| 222 // first one in the list. | 222 // first one in the list. |
| 223 next_connect_state_ = CONNECT_STATE_CONNECT; | 223 next_connect_state_ = CONNECT_STATE_CONNECT; |
| 224 current_ai_ = addresses_.head(); | 224 current_ai_ = addresses_.head(); |
| 225 | 225 |
| 226 int rv = DoConnectLoop(OK); | 226 int rv = DoConnectLoop(OK); |
| 227 if (rv == ERR_IO_PENDING) { | 227 if (rv == ERR_IO_PENDING) { |
| 228 // Synchronous operation not supported. | 228 // Synchronous operation not supported. |
| 229 DCHECK(callback); | 229 DCHECK(callback); |
| 230 old_write_callback_ = callback; | |
| 231 } else { | |
| 232 LogConnectCompletion(rv); | |
| 233 } | |
| 234 | |
| 235 return rv; | |
| 236 } | |
| 237 int TCPClientSocketLibevent::Connect(const CompletionCallback& callback) { | |
| 238 DCHECK(CalledOnValidThread()); | |
| 239 | |
| 240 // If already connected, then just return OK. | |
| 241 if (socket_ != kInvalidSocket) | |
| 242 return OK; | |
| 243 | |
| 244 base::StatsCounter connects("tcp.connect"); | |
| 245 connects.Increment(); | |
| 246 | |
| 247 DCHECK(!waiting_connect()); | |
| 248 | |
| 249 net_log_.BeginEvent( | |
| 250 NetLog::TYPE_TCP_CONNECT, | |
| 251 make_scoped_refptr(new AddressListNetLogParam(addresses_))); | |
| 252 | |
| 253 // We will try to connect to each address in addresses_. Start with the | |
| 254 // first one in the list. | |
| 255 next_connect_state_ = CONNECT_STATE_CONNECT; | |
| 256 current_ai_ = addresses_.head(); | |
| 257 | |
| 258 int rv = DoConnectLoop(OK); | |
| 259 if (rv == ERR_IO_PENDING) { | |
| 260 // Synchronous operation not supported. | |
| 261 DCHECK(!callback.is_null()); | |
| 230 write_callback_ = callback; | 262 write_callback_ = callback; |
| 231 } else { | 263 } else { |
| 232 LogConnectCompletion(rv); | 264 LogConnectCompletion(rv); |
| 233 } | 265 } |
| 234 | 266 |
| 235 return rv; | 267 return rv; |
| 236 } | 268 } |
| 237 | 269 |
| 238 int TCPClientSocketLibevent::DoConnectLoop(int result) { | 270 int TCPClientSocketLibevent::DoConnectLoop(int result) { |
| 239 DCHECK_NE(next_connect_state_, CONNECT_STATE_NONE); | 271 DCHECK_NE(next_connect_state_, CONNECT_STATE_NONE); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 466 read_callback_ = callback; | 498 read_callback_ = callback; |
| 467 return ERR_IO_PENDING; | 499 return ERR_IO_PENDING; |
| 468 } | 500 } |
| 469 | 501 |
| 470 int TCPClientSocketLibevent::Write(IOBuffer* buf, | 502 int TCPClientSocketLibevent::Write(IOBuffer* buf, |
| 471 int buf_len, | 503 int buf_len, |
| 472 OldCompletionCallback* callback) { | 504 OldCompletionCallback* callback) { |
| 473 DCHECK(CalledOnValidThread()); | 505 DCHECK(CalledOnValidThread()); |
| 474 DCHECK_NE(kInvalidSocket, socket_); | 506 DCHECK_NE(kInvalidSocket, socket_); |
| 475 DCHECK(!waiting_connect()); | 507 DCHECK(!waiting_connect()); |
| 476 DCHECK(!write_callback_); | 508 DCHECK(!old_write_callback_); |
|
csilv
2011/12/06 21:03:18
also check write_callback here?
James Hawkins
2011/12/06 22:19:30
Done.
| |
| 477 // Synchronous operation not supported | 509 // Synchronous operation not supported |
| 478 DCHECK(callback); | 510 DCHECK(callback); |
| 479 DCHECK_GT(buf_len, 0); | 511 DCHECK_GT(buf_len, 0); |
| 480 | 512 |
| 481 int nwrite = InternalWrite(buf, buf_len); | 513 int nwrite = InternalWrite(buf, buf_len); |
| 482 if (nwrite >= 0) { | 514 if (nwrite >= 0) { |
| 483 base::StatsCounter write_bytes("tcp.write_bytes"); | 515 base::StatsCounter write_bytes("tcp.write_bytes"); |
| 484 write_bytes.Add(nwrite); | 516 write_bytes.Add(nwrite); |
| 485 if (nwrite > 0) | 517 if (nwrite > 0) |
| 486 use_history_.set_was_used_to_convey_data(); | 518 use_history_.set_was_used_to_convey_data(); |
| 487 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, | 519 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, |
| 488 buf->data()); | 520 buf->data()); |
| 489 return nwrite; | 521 return nwrite; |
| 490 } | 522 } |
| 491 if (errno != EAGAIN && errno != EWOULDBLOCK) | 523 if (errno != EAGAIN && errno != EWOULDBLOCK) |
| 492 return MapSystemError(errno); | 524 return MapSystemError(errno); |
| 493 | 525 |
| 494 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 526 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 495 socket_, true, MessageLoopForIO::WATCH_WRITE, | 527 socket_, true, MessageLoopForIO::WATCH_WRITE, |
| 496 &write_socket_watcher_, &write_watcher_)) { | 528 &write_socket_watcher_, &write_watcher_)) { |
| 497 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; | 529 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; |
| 498 return MapSystemError(errno); | 530 return MapSystemError(errno); |
| 499 } | 531 } |
| 500 | 532 |
| 501 write_buf_ = buf; | 533 write_buf_ = buf; |
| 502 write_buf_len_ = buf_len; | 534 write_buf_len_ = buf_len; |
| 503 write_callback_ = callback; | 535 old_write_callback_ = callback; |
| 504 return ERR_IO_PENDING; | 536 return ERR_IO_PENDING; |
| 505 } | 537 } |
| 506 | 538 |
| 507 int TCPClientSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { | 539 int TCPClientSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { |
| 508 int nwrite; | 540 int nwrite; |
| 509 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) { | 541 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) { |
| 510 // We have a limited amount of data to send in the SYN packet. | 542 // We have a limited amount of data to send in the SYN packet. |
| 511 int kMaxFastOpenSendLength = 1420; | 543 int kMaxFastOpenSendLength = 1420; |
| 512 | 544 |
| 513 buf_len = std::min(kMaxFastOpenSendLength, buf_len); | 545 buf_len = std::min(kMaxFastOpenSendLength, buf_len); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 DCHECK(read_callback_); | 621 DCHECK(read_callback_); |
| 590 | 622 |
| 591 // since Run may result in Read being called, clear read_callback_ up front. | 623 // since Run may result in Read being called, clear read_callback_ up front. |
| 592 OldCompletionCallback* c = read_callback_; | 624 OldCompletionCallback* c = read_callback_; |
| 593 read_callback_ = NULL; | 625 read_callback_ = NULL; |
| 594 c->Run(rv); | 626 c->Run(rv); |
| 595 } | 627 } |
| 596 | 628 |
| 597 void TCPClientSocketLibevent::DoWriteCallback(int rv) { | 629 void TCPClientSocketLibevent::DoWriteCallback(int rv) { |
| 598 DCHECK_NE(rv, ERR_IO_PENDING); | 630 DCHECK_NE(rv, ERR_IO_PENDING); |
| 599 DCHECK(write_callback_); | 631 DCHECK(old_write_callback_ || !write_callback_.is_null()); |
| 600 | 632 |
| 601 // since Run may result in Write being called, clear write_callback_ up front. | 633 // since Run may result in Write being called, clear write_callback_ up front. |
| 602 OldCompletionCallback* c = write_callback_; | 634 if (old_write_callback_) { |
| 603 write_callback_ = NULL; | 635 OldCompletionCallback* c = old_write_callback_; |
| 604 c->Run(rv); | 636 old_write_callback_ = NULL; |
| 637 c->Run(rv); | |
| 638 } else { | |
| 639 CompletionCallback c = write_callback_; | |
| 640 write_callback_.Reset(); | |
| 641 c.Run(rv); | |
| 642 } | |
| 605 } | 643 } |
| 606 | 644 |
| 607 void TCPClientSocketLibevent::DidCompleteConnect() { | 645 void TCPClientSocketLibevent::DidCompleteConnect() { |
| 608 DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE); | 646 DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE); |
| 609 | 647 |
| 610 // Get the error that connect() completed with. | 648 // Get the error that connect() completed with. |
| 611 int os_error = 0; | 649 int os_error = 0; |
| 612 socklen_t len = sizeof(os_error); | 650 socklen_t len = sizeof(os_error); |
| 613 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &os_error, &len) < 0) | 651 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &os_error, &len) < 0) |
| 614 os_error = errno; | 652 os_error = errno; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 729 | 767 |
| 730 int64 TCPClientSocketLibevent::NumBytesRead() const { | 768 int64 TCPClientSocketLibevent::NumBytesRead() const { |
| 731 return num_bytes_read_; | 769 return num_bytes_read_; |
| 732 } | 770 } |
| 733 | 771 |
| 734 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { | 772 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { |
| 735 return connect_time_micros_; | 773 return connect_time_micros_; |
| 736 } | 774 } |
| 737 | 775 |
| 738 } // namespace net | 776 } // namespace net |
| OLD | NEW |