OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
950 LogConnectCompletion(rv); | 950 LogConnectCompletion(rv); |
951 DoReadCallback(rv); | 951 DoReadCallback(rv); |
952 } | 952 } |
953 } | 953 } |
954 | 954 |
955 void TCPClientSocketWin::DidCompleteRead() { | 955 void TCPClientSocketWin::DidCompleteRead() { |
956 DCHECK(waiting_read_); | 956 DCHECK(waiting_read_); |
957 DWORD num_bytes, flags; | 957 DWORD num_bytes, flags; |
958 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, | 958 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, |
959 &num_bytes, FALSE, &flags); | 959 &num_bytes, FALSE, &flags); |
960 WSAResetEvent(core_->read_overlapped_.hEvent); | |
961 waiting_read_ = false; | 960 waiting_read_ = false; |
962 int rv; | 961 int rv; |
963 if (ok) { | 962 if (ok) { |
964 base::StatsCounter read_bytes("tcp.read_bytes"); | 963 base::StatsCounter read_bytes("tcp.read_bytes"); |
965 read_bytes.Add(num_bytes); | 964 read_bytes.Add(num_bytes); |
966 num_bytes_read_ += num_bytes; | 965 num_bytes_read_ += num_bytes; |
967 if (num_bytes > 0) | 966 if (num_bytes > 0) |
968 use_history_.set_was_used_to_convey_data(); | 967 use_history_.set_was_used_to_convey_data(); |
969 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 968 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
970 num_bytes, core_->read_iobuffer_->data()); | 969 num_bytes, core_->read_iobuffer_->data()); |
971 rv = static_cast<int>(num_bytes); | 970 rv = static_cast<int>(num_bytes); |
972 } else { | 971 } else { |
973 int os_error = WSAGetLastError(); | 972 int os_error = WSAGetLastError(); |
974 rv = MapSystemError(os_error); | 973 rv = MapSystemError(os_error); |
975 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 974 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
976 CreateNetLogSocketErrorCallback(rv, os_error)); | 975 CreateNetLogSocketErrorCallback(rv, os_error)); |
977 } | 976 } |
977 WSAResetEvent(core_->read_overlapped_.hEvent); | |
978 core_->read_iobuffer_ = NULL; | 978 core_->read_iobuffer_ = NULL; |
979 core_->read_buffer_length_ = 0; | 979 core_->read_buffer_length_ = 0; |
980 DoReadCallback(rv); | 980 DoReadCallback(rv); |
981 } | 981 } |
982 | 982 |
983 void TCPClientSocketWin::DidCompleteWrite() { | 983 void TCPClientSocketWin::DidCompleteWrite() { |
984 DCHECK(waiting_write_); | 984 DCHECK(waiting_write_); |
985 | 985 |
986 DWORD num_bytes, flags; | 986 DWORD num_bytes, flags; |
987 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 987 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
(...skipping 30 matching lines...) Expand all Loading... | |
1018 | 1018 |
1019 void TCPClientSocketWin::DidSignalRead() { | 1019 void TCPClientSocketWin::DidSignalRead() { |
1020 DCHECK(waiting_read_); | 1020 DCHECK(waiting_read_); |
1021 int os_error = 0; | 1021 int os_error = 0; |
1022 WSANETWORKEVENTS network_events; | 1022 WSANETWORKEVENTS network_events; |
1023 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | 1023 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, |
1024 &network_events); | 1024 &network_events); |
1025 if (rv == SOCKET_ERROR) { | 1025 if (rv == SOCKET_ERROR) { |
1026 os_error = WSAGetLastError(); | 1026 os_error = WSAGetLastError(); |
1027 rv = MapSystemError(os_error); | 1027 rv = MapSystemError(os_error); |
1028 } else if (network_events.lNetworkEvents & FD_READ) { | 1028 } else if (network_events.lNetworkEvents) { |
1029 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_, | 1029 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); |
1030 read_callback_); | 1030 if (network_events.lNetworkEvents == FD_CLOSE && |
1031 if (rv == ERR_IO_PENDING) | 1031 network_events.iErrorCode[FD_CLOSE_BIT] == 0) { |
1032 return; | 1032 // Graceful connection closure. |
1033 } else if (network_events.lNetworkEvents & FD_CLOSE) { | 1033 // TODO(wtc): should we still call DoRead() in this case? The MSDN |
1034 if (network_events.iErrorCode[FD_CLOSE_BIT]) { | 1034 // page for WSAEventSelect says: |
1035 rv = MapSystemError(network_events.iErrorCode[FD_CLOSE_BIT]); | 1035 // An application should check for remaining data upon receipt |
1036 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 1036 // of FD_CLOSE to avoid any possibility of losing data. |
1037 CreateNetLogSocketErrorCallback(rv, os_error)); | 1037 rv = 0; |
wtc
2013/03/14 01:57:24
I added this case as a performance optimization. H
Pat Meenan
2013/03/14 13:46:47
I'd remove the special case since the docs indicat
wtc
2013/03/14 18:28:04
Done.
rvargas (doing something else)
2013/03/14 18:48:16
I think that the optimization is fine and the doc
| |
1038 } else { | 1038 } else { |
1039 rv = 0; | 1039 // If network_events.iErrorCode[FD_READ_BIT] or |
1040 // network_events.iErrorCode[FD_CLOSE_BIT] is nonzero, still call | |
1041 // DoRead() because recv() reports a more accurate error code | |
1042 // (WSAECONNRESET vs. WSAECONNABORTED) when the connection was | |
1043 // reset. | |
Pat Meenan
2013/03/14 13:46:47
Can you add to the comment after removing the spec
wtc
2013/03/14 18:28:04
Done.
| |
1044 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_, | |
1045 read_callback_); | |
1046 if (rv == ERR_IO_PENDING) | |
1047 return; | |
1040 } | 1048 } |
1041 } else { | 1049 } else { |
1042 // This should not happen but I have seen cases where we will get | 1050 // This may happen because Read() may succeed synchronously and |
1043 // signaled but the network events flags are all clear (0). | 1051 // consume all the received data without resetting the event object. |
1052 // Rather than trying to reset the event object properly, it seems | |
rvargas (doing something else)
2013/03/14 18:48:16
nit: I'd remove this second sentence because it im
| |
1053 // more efficient to skip the WSAResetEvent system call on | |
1054 // synchronous success of Read() and handle spurious wakeups here. | |
1044 core_->WatchForRead(); | 1055 core_->WatchForRead(); |
1045 return; | 1056 return; |
1046 } | 1057 } |
1047 waiting_read_ = false; | 1058 waiting_read_ = false; |
1048 core_->read_iobuffer_ = NULL; | 1059 core_->read_iobuffer_ = NULL; |
1049 core_->read_buffer_length_ = 0; | 1060 core_->read_buffer_length_ = 0; |
1050 DoReadCallback(rv); | 1061 DoReadCallback(rv); |
1051 } | 1062 } |
1052 | 1063 |
1053 } // namespace net | 1064 } // namespace net |
OLD | NEW |