Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: net/socket/tcp_client_socket_win.cc

Issue 12546004: Retrieve more accurate error code (WSAECONNRESET vs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698