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