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_ && write_callback_.is_null()); |
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 |