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 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 bound_socket_(INVALID_SOCKET), | 319 bound_socket_(INVALID_SOCKET), |
320 addresses_(addresses), | 320 addresses_(addresses), |
321 current_ai_(NULL), | 321 current_ai_(NULL), |
322 waiting_read_(false), | 322 waiting_read_(false), |
323 waiting_write_(false), | 323 waiting_write_(false), |
324 read_callback_(NULL), | 324 read_callback_(NULL), |
325 write_callback_(NULL), | 325 write_callback_(NULL), |
326 next_connect_state_(CONNECT_STATE_NONE), | 326 next_connect_state_(CONNECT_STATE_NONE), |
327 connect_os_error_(0), | 327 connect_os_error_(0), |
328 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 328 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
329 previously_disconnected_(false) { | 329 previously_disconnected_(false), |
| 330 num_bytes_read_(0), |
| 331 connect_time_micros_(-1) { |
330 scoped_refptr<NetLog::EventParameters> params; | 332 scoped_refptr<NetLog::EventParameters> params; |
331 if (source.is_valid()) | 333 if (source.is_valid()) |
332 params = new NetLogSourceParameter("source_dependency", source); | 334 params = new NetLogSourceParameter("source_dependency", source); |
333 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 335 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
334 EnsureWinsockInit(); | 336 EnsureWinsockInit(); |
335 } | 337 } |
336 | 338 |
337 TCPClientSocketWin::~TCPClientSocketWin() { | 339 TCPClientSocketWin::~TCPClientSocketWin() { |
338 Disconnect(); | 340 Disconnect(); |
339 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 341 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 core_ = new Core(this); | 482 core_ = new Core(this); |
481 | 483 |
482 // WSACreateEvent creates a manual-reset event object. | 484 // WSACreateEvent creates a manual-reset event object. |
483 core_->read_overlapped_.hEvent = WSACreateEvent(); | 485 core_->read_overlapped_.hEvent = WSACreateEvent(); |
484 // WSAEventSelect sets the socket to non-blocking mode as a side effect. | 486 // WSAEventSelect sets the socket to non-blocking mode as a side effect. |
485 // Our connect() and recv() calls require that the socket be non-blocking. | 487 // Our connect() and recv() calls require that the socket be non-blocking. |
486 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); | 488 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); |
487 | 489 |
488 core_->write_overlapped_.hEvent = WSACreateEvent(); | 490 core_->write_overlapped_.hEvent = WSACreateEvent(); |
489 | 491 |
| 492 connect_start_time_ = base::TimeTicks::Now(); |
490 if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) { | 493 if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) { |
491 // Connected without waiting! | 494 // Connected without waiting! |
492 // | 495 // |
493 // The MSDN page for connect says: | 496 // The MSDN page for connect says: |
494 // With a nonblocking socket, the connection attempt cannot be completed | 497 // With a nonblocking socket, the connection attempt cannot be completed |
495 // immediately. In this case, connect will return SOCKET_ERROR, and | 498 // immediately. In this case, connect will return SOCKET_ERROR, and |
496 // WSAGetLastError will return WSAEWOULDBLOCK. | 499 // WSAGetLastError will return WSAEWOULDBLOCK. |
497 // which implies that for a nonblocking socket, connect never returns 0. | 500 // which implies that for a nonblocking socket, connect never returns 0. |
498 // It's not documented whether the event object will be signaled or not | 501 // It's not documented whether the event object will be signaled or not |
499 // if connect does return 0. So the code below is essentially dead code | 502 // if connect does return 0. So the code below is essentially dead code |
(...skipping 18 matching lines...) Expand all Loading... |
518 int TCPClientSocketWin::DoConnectComplete(int result) { | 521 int TCPClientSocketWin::DoConnectComplete(int result) { |
519 // Log the end of this attempt (and any OS error it threw). | 522 // Log the end of this attempt (and any OS error it threw). |
520 int os_error = connect_os_error_; | 523 int os_error = connect_os_error_; |
521 connect_os_error_ = 0; | 524 connect_os_error_ = 0; |
522 scoped_refptr<NetLog::EventParameters> params; | 525 scoped_refptr<NetLog::EventParameters> params; |
523 if (result != OK) | 526 if (result != OK) |
524 params = new NetLogIntegerParameter("os_error", os_error); | 527 params = new NetLogIntegerParameter("os_error", os_error); |
525 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); | 528 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); |
526 | 529 |
527 if (result == OK) { | 530 if (result == OK) { |
| 531 connect_time_micros_ = (base::TimeTicks::Now() - |
| 532 connect_start_time_).ToInternalValue(); |
528 use_history_.set_was_ever_connected(); | 533 use_history_.set_was_ever_connected(); |
529 return OK; // Done! | 534 return OK; // Done! |
530 } | 535 } |
531 | 536 |
532 // Close whatever partially connected socket we currently have. | 537 // Close whatever partially connected socket we currently have. |
533 DoDisconnect(); | 538 DoDisconnect(); |
534 | 539 |
535 // Try to fall back to the next address in the list. | 540 // Try to fall back to the next address in the list. |
536 if (current_ai_->ai_next) { | 541 if (current_ai_->ai_next) { |
537 next_connect_state_ = CONNECT_STATE_CONNECT; | 542 next_connect_state_ = CONNECT_STATE_CONNECT; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | 689 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
685 // Because of how WSARecv fills memory when used asynchronously, Purify | 690 // Because of how WSARecv fills memory when used asynchronously, Purify |
686 // isn't able to detect that it's been initialized, so it scans for 0xcd | 691 // isn't able to detect that it's been initialized, so it scans for 0xcd |
687 // in the buffer and reports UMRs (uninitialized memory reads) for those | 692 // in the buffer and reports UMRs (uninitialized memory reads) for those |
688 // individual bytes. We override that in PURIFY builds to avoid the | 693 // individual bytes. We override that in PURIFY builds to avoid the |
689 // false error reports. | 694 // false error reports. |
690 // See bug 5297. | 695 // See bug 5297. |
691 base::MemoryDebug::MarkAsInitialized(core_->read_buffer_.buf, num); | 696 base::MemoryDebug::MarkAsInitialized(core_->read_buffer_.buf, num); |
692 base::StatsCounter read_bytes("tcp.read_bytes"); | 697 base::StatsCounter read_bytes("tcp.read_bytes"); |
693 read_bytes.Add(num); | 698 read_bytes.Add(num); |
| 699 num_bytes_read_ += num; |
694 if (num > 0) | 700 if (num > 0) |
695 use_history_.set_was_used_to_convey_data(); | 701 use_history_.set_was_used_to_convey_data(); |
696 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, | 702 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, |
697 core_->read_buffer_.buf); | 703 core_->read_buffer_.buf); |
698 return static_cast<int>(num); | 704 return static_cast<int>(num); |
699 } | 705 } |
700 } else { | 706 } else { |
701 int os_error = WSAGetLastError(); | 707 int os_error = WSAGetLastError(); |
702 if (os_error != WSA_IO_PENDING) | 708 if (os_error != WSA_IO_PENDING) |
703 return MapSystemError(os_error); | 709 return MapSystemError(os_error); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 DCHECK(waiting_read_); | 860 DCHECK(waiting_read_); |
855 DWORD num_bytes, flags; | 861 DWORD num_bytes, flags; |
856 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, | 862 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, |
857 &num_bytes, FALSE, &flags); | 863 &num_bytes, FALSE, &flags); |
858 WSAResetEvent(core_->read_overlapped_.hEvent); | 864 WSAResetEvent(core_->read_overlapped_.hEvent); |
859 waiting_read_ = false; | 865 waiting_read_ = false; |
860 core_->read_iobuffer_ = NULL; | 866 core_->read_iobuffer_ = NULL; |
861 if (ok) { | 867 if (ok) { |
862 base::StatsCounter read_bytes("tcp.read_bytes"); | 868 base::StatsCounter read_bytes("tcp.read_bytes"); |
863 read_bytes.Add(num_bytes); | 869 read_bytes.Add(num_bytes); |
| 870 num_bytes_read_ += num_bytes; |
864 if (num_bytes > 0) | 871 if (num_bytes > 0) |
865 use_history_.set_was_used_to_convey_data(); | 872 use_history_.set_was_used_to_convey_data(); |
866 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 873 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
867 num_bytes, core_->read_buffer_.buf); | 874 num_bytes, core_->read_buffer_.buf); |
868 } | 875 } |
869 DoReadCallback(ok ? num_bytes : MapSystemError(WSAGetLastError())); | 876 DoReadCallback(ok ? num_bytes : MapSystemError(WSAGetLastError())); |
870 } | 877 } |
871 | 878 |
872 void TCPClientSocketWin::DidCompleteWrite() { | 879 void TCPClientSocketWin::DidCompleteWrite() { |
873 DCHECK(waiting_write_); | 880 DCHECK(waiting_write_); |
(...skipping 22 matching lines...) Expand all Loading... |
896 use_history_.set_was_used_to_convey_data(); | 903 use_history_.set_was_used_to_convey_data(); |
897 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, | 904 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, |
898 core_->write_buffer_.buf); | 905 core_->write_buffer_.buf); |
899 } | 906 } |
900 } | 907 } |
901 core_->write_iobuffer_ = NULL; | 908 core_->write_iobuffer_ = NULL; |
902 DoWriteCallback(rv); | 909 DoWriteCallback(rv); |
903 } | 910 } |
904 | 911 |
905 } // namespace net | 912 } // namespace net |
OLD | NEW |