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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle; | 259 static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle; |
260 int slow_start_throttle_; | 260 int slow_start_throttle_; |
261 | 261 |
262 DISALLOW_COPY_AND_ASSIGN(Core); | 262 DISALLOW_COPY_AND_ASSIGN(Core); |
263 }; | 263 }; |
264 | 264 |
265 TCPClientSocketWin::Core::Core( | 265 TCPClientSocketWin::Core::Core( |
266 TCPClientSocketWin* socket) | 266 TCPClientSocketWin* socket) |
267 : read_buffer_length_(0), | 267 : read_buffer_length_(0), |
268 write_buffer_length_(0), | 268 write_buffer_length_(0), |
269 disable_overlapped_reads_(g_disable_overlapped_reads), | 269 disable_overlapped_reads_(true), |
wtc
2013/03/06 17:33:43
Please ignore this change. I need this temporary c
| |
270 non_blocking_reads_initialized_(false), | 270 non_blocking_reads_initialized_(false), |
271 socket_(socket), | 271 socket_(socket), |
272 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), | 272 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), |
273 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)), | 273 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)), |
274 slow_start_throttle_(kInitialSlowStartThrottle) { | 274 slow_start_throttle_(kInitialSlowStartThrottle) { |
275 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 275 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
276 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 276 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
277 | 277 |
278 read_overlapped_.hEvent = WSACreateEvent(); | 278 read_overlapped_.hEvent = WSACreateEvent(); |
279 write_overlapped_.hEvent = WSACreateEvent(); | 279 write_overlapped_.hEvent = WSACreateEvent(); |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
833 } | 833 } |
834 | 834 |
835 int TCPClientSocketWin::DoRead(IOBuffer* buf, int buf_len, | 835 int TCPClientSocketWin::DoRead(IOBuffer* buf, int buf_len, |
836 const CompletionCallback& callback) { | 836 const CompletionCallback& callback) { |
837 if (core_->disable_overlapped_reads_) { | 837 if (core_->disable_overlapped_reads_) { |
838 if (!core_->non_blocking_reads_initialized_) { | 838 if (!core_->non_blocking_reads_initialized_) { |
839 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, | 839 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, |
840 FD_READ | FD_CLOSE); | 840 FD_READ | FD_CLOSE); |
841 core_->non_blocking_reads_initialized_ = true; | 841 core_->non_blocking_reads_initialized_ = true; |
842 } | 842 } |
843 // Sometimes core_->read_overlapped_.hEvent is signaled at this | |
844 // point. It is usually the 3rd-5th times we call recv() on the | |
845 // socket, never the first time. | |
843 int rv = recv(socket_, buf->data(), buf_len, 0); | 846 int rv = recv(socket_, buf->data(), buf_len, 0); |
844 if (rv == SOCKET_ERROR) { | 847 if (rv == SOCKET_ERROR) { |
845 int os_error = WSAGetLastError(); | 848 int os_error = WSAGetLastError(); |
846 if (os_error != WSAEWOULDBLOCK) { | 849 if (os_error != WSAEWOULDBLOCK) { |
847 int net_error = MapSystemError(os_error); | 850 int net_error = MapSystemError(os_error); |
848 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 851 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
849 CreateNetLogSocketErrorCallback(net_error, os_error)); | 852 CreateNetLogSocketErrorCallback(net_error, os_error)); |
850 return net_error; | 853 return net_error; |
851 } | 854 } |
852 } else { | 855 } else { |
853 base::StatsCounter read_bytes("tcp.read_bytes"); | 856 base::StatsCounter read_bytes("tcp.read_bytes"); |
854 if (rv > 0) { | 857 if (rv > 0) { |
855 use_history_.set_was_used_to_convey_data(); | 858 use_history_.set_was_used_to_convey_data(); |
856 read_bytes.Add(rv); | 859 read_bytes.Add(rv); |
857 num_bytes_read_ += rv; | 860 num_bytes_read_ += rv; |
858 } | 861 } |
859 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, | 862 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, |
860 buf->data()); | 863 buf->data()); |
864 BOOL ok = WSAResetEvent(core_->read_overlapped_.hEvent); | |
rvargas (doing something else)
2013/03/06 23:08:49
I think this can cause unwanted hangs (unlikely, b
Pat Meenan
2013/03/07 15:11:04
What are you trying to solve by manually resetting
| |
865 CHECK(ok); | |
861 return rv; | 866 return rv; |
862 } | 867 } |
863 } else { | 868 } else { |
864 buf_len = core_->ThrottleReadSize(buf_len); | 869 buf_len = core_->ThrottleReadSize(buf_len); |
865 | 870 |
866 WSABUF read_buffer; | 871 WSABUF read_buffer; |
867 read_buffer.len = buf_len; | 872 read_buffer.len = buf_len; |
868 read_buffer.buf = buf->data(); | 873 read_buffer.buf = buf->data(); |
869 | 874 |
870 // TODO(wtc): Remove the assertion after enough testing. | 875 // TODO(wtc): Remove the assertion after enough testing. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1015 core_->write_iobuffer_ = NULL; | 1020 core_->write_iobuffer_ = NULL; |
1016 DoWriteCallback(rv); | 1021 DoWriteCallback(rv); |
1017 } | 1022 } |
1018 | 1023 |
1019 void TCPClientSocketWin::DidSignalRead() { | 1024 void TCPClientSocketWin::DidSignalRead() { |
1020 DCHECK(waiting_read_); | 1025 DCHECK(waiting_read_); |
1021 int os_error = 0; | 1026 int os_error = 0; |
1022 WSANETWORKEVENTS network_events; | 1027 WSANETWORKEVENTS network_events; |
1023 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | 1028 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, |
1024 &network_events); | 1029 &network_events); |
1030 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | |
wtc
2013/03/06 17:33:43
This asserts that WSAEnumNetworkEvents resets the
rvargas (doing something else)
2013/03/06 23:08:49
Sounds like a race to me.
Pat Meenan
2013/03/07 15:11:04
Agreed, it's not atomic so it's theoretically poss
| |
1025 if (rv == SOCKET_ERROR) { | 1031 if (rv == SOCKET_ERROR) { |
1032 NOTREACHED(); | |
rvargas (doing something else)
2013/03/06 23:08:49
I'm assuming this is for development purposes... I
| |
1026 os_error = WSAGetLastError(); | 1033 os_error = WSAGetLastError(); |
1027 rv = MapSystemError(os_error); | 1034 rv = MapSystemError(os_error); |
1028 } else if (network_events.lNetworkEvents & FD_READ) { | 1035 } else if (network_events.lNetworkEvents) { |
1029 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_, | 1036 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_, |
1030 read_callback_); | 1037 read_callback_); |
wtc
2013/03/06 17:33:43
I got the inspiration of this change from the old-
Pat Meenan
2013/03/07 15:11:04
Is the last error from the recv() here as granular
wtc
2013/03/14 01:24:45
Yes, in fact it is better.
When the peer resets t
| |
1031 if (rv == ERR_IO_PENDING) | 1038 if (rv == ERR_IO_PENDING) |
1032 return; | 1039 return; |
1033 } else if (network_events.lNetworkEvents & FD_CLOSE) { | |
1034 if (network_events.iErrorCode[FD_CLOSE_BIT]) { | |
1035 rv = MapSystemError(network_events.iErrorCode[FD_CLOSE_BIT]); | |
1036 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | |
1037 CreateNetLogSocketErrorCallback(rv, os_error)); | |
wtc
2013/03/06 17:33:43
If you prefer a smaller change, I can call DoRead(
| |
1038 } else { | |
1039 rv = 0; | |
1040 } | |
1041 } else { | 1040 } else { |
1042 // This should not happen but I have seen cases where we will get | 1041 // This should not happen but I have seen cases where we will get |
1043 // signaled but the network events flags are all clear (0). | 1042 // signaled but the network events flags are all clear (0). |
wtc
2013/03/06 17:33:43
The WSAResetEvent call I added on line 864 elimina
rvargas (doing something else)
2013/03/06 23:08:49
I'm thinking that we either accept a spurious wake
Pat Meenan
2013/03/07 15:11:04
How often do the Spurious wake-ups happen from IsC
wtc
2013/03/14 01:24:45
I confirmed that the spurious wake-ups are NOT cau
| |
1043 NOTREACHED(); | |
rvargas (doing something else)
2013/03/06 23:08:49
same thing here. If this triggers for a developer
| |
1044 core_->WatchForRead(); | 1044 core_->WatchForRead(); |
1045 return; | 1045 return; |
1046 } | 1046 } |
1047 waiting_read_ = false; | 1047 waiting_read_ = false; |
1048 core_->read_iobuffer_ = NULL; | 1048 core_->read_iobuffer_ = NULL; |
1049 core_->read_buffer_length_ = 0; | 1049 core_->read_buffer_length_ = 0; |
1050 DoReadCallback(rv); | 1050 DoReadCallback(rv); |
1051 } | 1051 } |
1052 | 1052 |
1053 } // namespace net | 1053 } // namespace net |
OLD | NEW |