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_win.h" | 5 #include "net/socket/tcp_client_socket_win.h" |
6 | 6 |
7 #include <mstcpip.h> | 7 #include <mstcpip.h> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 bound_socket_(INVALID_SOCKET), | 316 bound_socket_(INVALID_SOCKET), |
317 addresses_(addresses), | 317 addresses_(addresses), |
318 current_ai_(NULL), | 318 current_ai_(NULL), |
319 waiting_read_(false), | 319 waiting_read_(false), |
320 waiting_write_(false), | 320 waiting_write_(false), |
321 read_callback_(NULL), | 321 read_callback_(NULL), |
322 write_callback_(NULL), | 322 write_callback_(NULL), |
323 next_connect_state_(CONNECT_STATE_NONE), | 323 next_connect_state_(CONNECT_STATE_NONE), |
324 connect_os_error_(0), | 324 connect_os_error_(0), |
325 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 325 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
326 previously_disconnected_(false) { | 326 previously_disconnected_(false), |
| 327 num_bytes_read_(0), |
| 328 connect_time_micros_(-1) { |
327 scoped_refptr<NetLog::EventParameters> params; | 329 scoped_refptr<NetLog::EventParameters> params; |
328 if (source.is_valid()) | 330 if (source.is_valid()) |
329 params = new NetLogSourceParameter("source_dependency", source); | 331 params = new NetLogSourceParameter("source_dependency", source); |
330 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 332 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
331 EnsureWinsockInit(); | 333 EnsureWinsockInit(); |
332 } | 334 } |
333 | 335 |
334 TCPClientSocketWin::~TCPClientSocketWin() { | 336 TCPClientSocketWin::~TCPClientSocketWin() { |
335 Disconnect(); | 337 Disconnect(); |
336 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 338 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 core_ = new Core(this); | 479 core_ = new Core(this); |
478 | 480 |
479 // WSACreateEvent creates a manual-reset event object. | 481 // WSACreateEvent creates a manual-reset event object. |
480 core_->read_overlapped_.hEvent = WSACreateEvent(); | 482 core_->read_overlapped_.hEvent = WSACreateEvent(); |
481 // WSAEventSelect sets the socket to non-blocking mode as a side effect. | 483 // WSAEventSelect sets the socket to non-blocking mode as a side effect. |
482 // Our connect() and recv() calls require that the socket be non-blocking. | 484 // Our connect() and recv() calls require that the socket be non-blocking. |
483 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); | 485 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); |
484 | 486 |
485 core_->write_overlapped_.hEvent = WSACreateEvent(); | 487 core_->write_overlapped_.hEvent = WSACreateEvent(); |
486 | 488 |
| 489 connect_start_time_ = base::TimeTicks::Now(); |
487 if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) { | 490 if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) { |
488 // Connected without waiting! | 491 // Connected without waiting! |
489 // | 492 // |
490 // The MSDN page for connect says: | 493 // The MSDN page for connect says: |
491 // With a nonblocking socket, the connection attempt cannot be completed | 494 // With a nonblocking socket, the connection attempt cannot be completed |
492 // immediately. In this case, connect will return SOCKET_ERROR, and | 495 // immediately. In this case, connect will return SOCKET_ERROR, and |
493 // WSAGetLastError will return WSAEWOULDBLOCK. | 496 // WSAGetLastError will return WSAEWOULDBLOCK. |
494 // which implies that for a nonblocking socket, connect never returns 0. | 497 // which implies that for a nonblocking socket, connect never returns 0. |
495 // It's not documented whether the event object will be signaled or not | 498 // It's not documented whether the event object will be signaled or not |
496 // if connect does return 0. So the code below is essentially dead code | 499 // if connect does return 0. So the code below is essentially dead code |
(...skipping 18 matching lines...) Expand all Loading... |
515 int TCPClientSocketWin::DoConnectComplete(int result) { | 518 int TCPClientSocketWin::DoConnectComplete(int result) { |
516 // Log the end of this attempt (and any OS error it threw). | 519 // Log the end of this attempt (and any OS error it threw). |
517 int os_error = connect_os_error_; | 520 int os_error = connect_os_error_; |
518 connect_os_error_ = 0; | 521 connect_os_error_ = 0; |
519 scoped_refptr<NetLog::EventParameters> params; | 522 scoped_refptr<NetLog::EventParameters> params; |
520 if (result != OK) | 523 if (result != OK) |
521 params = new NetLogIntegerParameter("os_error", os_error); | 524 params = new NetLogIntegerParameter("os_error", os_error); |
522 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); | 525 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); |
523 | 526 |
524 if (result == OK) { | 527 if (result == OK) { |
| 528 connect_time_micros_ = (base::TimeTicks::Now() - |
| 529 connect_start_time_).ToInternalValue(); |
525 use_history_.set_was_ever_connected(); | 530 use_history_.set_was_ever_connected(); |
526 return OK; // Done! | 531 return OK; // Done! |
527 } | 532 } |
528 | 533 |
529 // Close whatever partially connected socket we currently have. | 534 // Close whatever partially connected socket we currently have. |
530 DoDisconnect(); | 535 DoDisconnect(); |
531 | 536 |
532 // Try to fall back to the next address in the list. | 537 // Try to fall back to the next address in the list. |
533 if (current_ai_->ai_next) { | 538 if (current_ai_->ai_next) { |
534 next_connect_state_ = CONNECT_STATE_CONNECT; | 539 next_connect_state_ = CONNECT_STATE_CONNECT; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 | 656 |
652 bool TCPClientSocketWin::WasEverUsed() const { | 657 bool TCPClientSocketWin::WasEverUsed() const { |
653 return use_history_.was_used_to_convey_data(); | 658 return use_history_.was_used_to_convey_data(); |
654 } | 659 } |
655 | 660 |
656 bool TCPClientSocketWin::UsingTCPFastOpen() const { | 661 bool TCPClientSocketWin::UsingTCPFastOpen() const { |
657 // Not supported on windows. | 662 // Not supported on windows. |
658 return false; | 663 return false; |
659 } | 664 } |
660 | 665 |
| 666 int64 TCPClientSocketWin::NumBytesRead() const { |
| 667 return num_bytes_read_; |
| 668 } |
| 669 |
| 670 int TCPClientSocketWin::GetConnectTimeMicros() const { |
| 671 return connect_time_micros_; |
| 672 } |
| 673 |
661 int TCPClientSocketWin::Read(IOBuffer* buf, | 674 int TCPClientSocketWin::Read(IOBuffer* buf, |
662 int buf_len, | 675 int buf_len, |
663 CompletionCallback* callback) { | 676 CompletionCallback* callback) { |
664 DCHECK(CalledOnValidThread()); | 677 DCHECK(CalledOnValidThread()); |
665 DCHECK_NE(socket_, INVALID_SOCKET); | 678 DCHECK_NE(socket_, INVALID_SOCKET); |
666 DCHECK(!waiting_read_); | 679 DCHECK(!waiting_read_); |
667 DCHECK(!read_callback_); | 680 DCHECK(!read_callback_); |
668 DCHECK(!core_->read_iobuffer_); | 681 DCHECK(!core_->read_iobuffer_); |
669 | 682 |
670 buf_len = core_->ThrottleReadSize(buf_len); | 683 buf_len = core_->ThrottleReadSize(buf_len); |
(...skipping 10 matching lines...) Expand all Loading... |
681 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | 694 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
682 // Because of how WSARecv fills memory when used asynchronously, Purify | 695 // Because of how WSARecv fills memory when used asynchronously, Purify |
683 // isn't able to detect that it's been initialized, so it scans for 0xcd | 696 // isn't able to detect that it's been initialized, so it scans for 0xcd |
684 // in the buffer and reports UMRs (uninitialized memory reads) for those | 697 // in the buffer and reports UMRs (uninitialized memory reads) for those |
685 // individual bytes. We override that in PURIFY builds to avoid the | 698 // individual bytes. We override that in PURIFY builds to avoid the |
686 // false error reports. | 699 // false error reports. |
687 // See bug 5297. | 700 // See bug 5297. |
688 base::MemoryDebug::MarkAsInitialized(core_->read_buffer_.buf, num); | 701 base::MemoryDebug::MarkAsInitialized(core_->read_buffer_.buf, num); |
689 base::StatsCounter read_bytes("tcp.read_bytes"); | 702 base::StatsCounter read_bytes("tcp.read_bytes"); |
690 read_bytes.Add(num); | 703 read_bytes.Add(num); |
| 704 num_bytes_read_ += num; |
691 if (num > 0) | 705 if (num > 0) |
692 use_history_.set_was_used_to_convey_data(); | 706 use_history_.set_was_used_to_convey_data(); |
693 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, | 707 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, |
694 core_->read_buffer_.buf); | 708 core_->read_buffer_.buf); |
695 return static_cast<int>(num); | 709 return static_cast<int>(num); |
696 } | 710 } |
697 } else { | 711 } else { |
698 int os_error = WSAGetLastError(); | 712 int os_error = WSAGetLastError(); |
699 if (os_error != WSA_IO_PENDING) | 713 if (os_error != WSA_IO_PENDING) |
700 return MapSystemError(os_error); | 714 return MapSystemError(os_error); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 DCHECK(waiting_read_); | 865 DCHECK(waiting_read_); |
852 DWORD num_bytes, flags; | 866 DWORD num_bytes, flags; |
853 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, | 867 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, |
854 &num_bytes, FALSE, &flags); | 868 &num_bytes, FALSE, &flags); |
855 WSAResetEvent(core_->read_overlapped_.hEvent); | 869 WSAResetEvent(core_->read_overlapped_.hEvent); |
856 waiting_read_ = false; | 870 waiting_read_ = false; |
857 core_->read_iobuffer_ = NULL; | 871 core_->read_iobuffer_ = NULL; |
858 if (ok) { | 872 if (ok) { |
859 base::StatsCounter read_bytes("tcp.read_bytes"); | 873 base::StatsCounter read_bytes("tcp.read_bytes"); |
860 read_bytes.Add(num_bytes); | 874 read_bytes.Add(num_bytes); |
| 875 num_bytes_read_ += num_bytes; |
861 if (num_bytes > 0) | 876 if (num_bytes > 0) |
862 use_history_.set_was_used_to_convey_data(); | 877 use_history_.set_was_used_to_convey_data(); |
863 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 878 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
864 num_bytes, core_->read_buffer_.buf); | 879 num_bytes, core_->read_buffer_.buf); |
865 } | 880 } |
866 DoReadCallback(ok ? num_bytes : MapSystemError(WSAGetLastError())); | 881 DoReadCallback(ok ? num_bytes : MapSystemError(WSAGetLastError())); |
867 } | 882 } |
868 | 883 |
869 void TCPClientSocketWin::DidCompleteWrite() { | 884 void TCPClientSocketWin::DidCompleteWrite() { |
870 DCHECK(waiting_write_); | 885 DCHECK(waiting_write_); |
(...skipping 22 matching lines...) Expand all Loading... |
893 use_history_.set_was_used_to_convey_data(); | 908 use_history_.set_was_used_to_convey_data(); |
894 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, | 909 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, |
895 core_->write_buffer_.buf); | 910 core_->write_buffer_.buf); |
896 } | 911 } |
897 } | 912 } |
898 core_->write_iobuffer_ = NULL; | 913 core_->write_iobuffer_ = NULL; |
899 DoWriteCallback(rv); | 914 DoWriteCallback(rv); |
900 } | 915 } |
901 | 916 |
902 } // namespace net | 917 } // namespace net |
OLD | NEW |