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 |