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