| 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 |