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

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

Issue 10916016: Switch the TCP reads on Windows to use non-blocking/non-async I/O. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 2 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
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 10 matching lines...) Expand all
21 #include "net/base/network_change_notifier.h" 21 #include "net/base/network_change_notifier.h"
22 #include "net/base/winsock_init.h" 22 #include "net/base/winsock_init.h"
23 #include "net/base/winsock_util.h" 23 #include "net/base/winsock_util.h"
24 #include "net/socket/socket_net_log_params.h" 24 #include "net/socket/socket_net_log_params.h"
25 25
26 namespace net { 26 namespace net {
27 27
28 namespace { 28 namespace {
29 29
30 const int kTCPKeepAliveSeconds = 45; 30 const int kTCPKeepAliveSeconds = 45;
31 bool g_disable_overlapped_reads = false;
31 32
32 bool SetSocketReceiveBufferSize(SOCKET socket, int32 size) { 33 bool SetSocketReceiveBufferSize(SOCKET socket, int32 size) {
33 int rv = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, 34 int rv = setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
34 reinterpret_cast<const char*>(&size), sizeof(size)); 35 reinterpret_cast<const char*>(&size), sizeof(size));
35 DCHECK(!rv) << "Could not set socket receive buffer size: " << GetLastError(); 36 DCHECK(!rv) << "Could not set socket receive buffer size: " << GetLastError();
36 return rv == 0; 37 return rv == 0;
37 } 38 }
38 39
39 bool SetSocketSendBufferSize(SOCKET socket, int32 size) { 40 bool SetSocketSendBufferSize(SOCKET socket, int32 size) {
40 int rv = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, 41 int rv = setsockopt(socket, SOL_SOCKET, SO_SNDBUF,
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 public: 176 public:
176 explicit Core(TCPClientSocketWin* socket); 177 explicit Core(TCPClientSocketWin* socket);
177 178
178 // Start watching for the end of a read or write operation. 179 // Start watching for the end of a read or write operation.
179 void WatchForRead(); 180 void WatchForRead();
180 void WatchForWrite(); 181 void WatchForWrite();
181 182
182 // The TCPClientSocketWin is going away. 183 // The TCPClientSocketWin is going away.
183 void Detach() { socket_ = NULL; } 184 void Detach() { socket_ = NULL; }
184 185
186 // Throttle the read size based on our current slow start state.
187 // Returns the throttled read size.
188 int ThrottleReadSize(int size) {
189 if (slow_start_throttle_ < kMaxSlowStartThrottle) {
190 size = std::min(size, slow_start_throttle_);
191 slow_start_throttle_ *= 2;
192 }
193 return size;
194 }
195
185 // The separate OVERLAPPED variables for asynchronous operation. 196 // The separate OVERLAPPED variables for asynchronous operation.
186 // |read_overlapped_| is used for both Connect() and Read(). 197 // |read_overlapped_| is used for both Connect() and Read().
187 // |write_overlapped_| is only used for Write(); 198 // |write_overlapped_| is only used for Write();
188 OVERLAPPED read_overlapped_; 199 OVERLAPPED read_overlapped_;
189 OVERLAPPED write_overlapped_; 200 OVERLAPPED write_overlapped_;
190 201
191 // The buffers used in Read() and Write(). 202 // The buffers used in Read() and Write().
192 scoped_refptr<IOBuffer> read_iobuffer_; 203 scoped_refptr<IOBuffer> read_iobuffer_;
193 scoped_refptr<IOBuffer> write_iobuffer_; 204 scoped_refptr<IOBuffer> write_iobuffer_;
205 int read_buffer_length_;
194 int write_buffer_length_; 206 int write_buffer_length_;
195 207
196 // Throttle the read size based on our current slow start state. 208 // Remember the state of g_disable_overlapped_reads for the duration of the
197 // Returns the throttled read size. 209 // socket based on what it was when the socket was created.
198 int ThrottleReadSize(int size) { 210 bool disable_overlapped_reads_;
199 if (slow_start_throttle_ < kMaxSlowStartThrottle) { 211 bool non_blocking_reads_initialized_;
200 size = std::min(size, slow_start_throttle_);
201 slow_start_throttle_ *= 2;
202 }
203 return size;
204 }
205 212
206 private: 213 private:
207 friend class base::RefCounted<Core>; 214 friend class base::RefCounted<Core>;
208 215
209 class ReadDelegate : public base::win::ObjectWatcher::Delegate { 216 class ReadDelegate : public base::win::ObjectWatcher::Delegate {
210 public: 217 public:
211 explicit ReadDelegate(Core* core) : core_(core) {} 218 explicit ReadDelegate(Core* core) : core_(core) {}
212 virtual ~ReadDelegate() {} 219 virtual ~ReadDelegate() {}
213 220
214 // base::ObjectWatcher::Delegate methods: 221 // base::ObjectWatcher::Delegate methods:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 // returning data to the application. 257 // returning data to the application.
251 static const int kInitialSlowStartThrottle = 1 * 1024; 258 static const int kInitialSlowStartThrottle = 1 * 1024;
252 static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle; 259 static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle;
253 int slow_start_throttle_; 260 int slow_start_throttle_;
254 261
255 DISALLOW_COPY_AND_ASSIGN(Core); 262 DISALLOW_COPY_AND_ASSIGN(Core);
256 }; 263 };
257 264
258 TCPClientSocketWin::Core::Core( 265 TCPClientSocketWin::Core::Core(
259 TCPClientSocketWin* socket) 266 TCPClientSocketWin* socket)
260 : write_buffer_length_(0), 267 : read_buffer_length_(0),
268 write_buffer_length_(0),
269 disable_overlapped_reads_(g_disable_overlapped_reads),
270 non_blocking_reads_initialized_(false),
261 socket_(socket), 271 socket_(socket),
262 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), 272 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)),
263 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)), 273 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)),
264 slow_start_throttle_(kInitialSlowStartThrottle) { 274 slow_start_throttle_(kInitialSlowStartThrottle) {
265 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); 275 memset(&read_overlapped_, 0, sizeof(read_overlapped_));
266 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); 276 memset(&write_overlapped_, 0, sizeof(write_overlapped_));
267 277
268 read_overlapped_.hEvent = WSACreateEvent(); 278 read_overlapped_.hEvent = WSACreateEvent();
269 write_overlapped_.hEvent = WSACreateEvent(); 279 write_overlapped_.hEvent = WSACreateEvent();
270 } 280 }
(...skipping 23 matching lines...) Expand all
294 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_); 304 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_);
295 } 305 }
296 306
297 void TCPClientSocketWin::Core::ReadDelegate::OnObjectSignaled( 307 void TCPClientSocketWin::Core::ReadDelegate::OnObjectSignaled(
298 HANDLE object) { 308 HANDLE object) {
299 DCHECK_EQ(object, core_->read_overlapped_.hEvent); 309 DCHECK_EQ(object, core_->read_overlapped_.hEvent);
300 if (core_->socket_) { 310 if (core_->socket_) {
301 if (core_->socket_->waiting_connect()) { 311 if (core_->socket_->waiting_connect()) {
302 core_->socket_->DidCompleteConnect(); 312 core_->socket_->DidCompleteConnect();
303 } else { 313 } else {
304 core_->socket_->DidCompleteRead(); 314 if (core_->disable_overlapped_reads_) {
slamm 2012/10/25 19:51:48 Change 313 to "else if".
pmeenan 2012/10/26 14:03:49 Done.
315 core_->socket_->DidSignalRead();
316 } else {
317 core_->socket_->DidCompleteRead();
318 }
305 } 319 }
306 } 320 }
307 321
308 core_->Release(); 322 core_->Release();
309 } 323 }
310 324
311 void TCPClientSocketWin::Core::WriteDelegate::OnObjectSignaled( 325 void TCPClientSocketWin::Core::WriteDelegate::OnObjectSignaled(
312 HANDLE object) { 326 HANDLE object) {
313 DCHECK_EQ(object, core_->write_overlapped_.hEvent); 327 DCHECK_EQ(object, core_->write_overlapped_.hEvent);
314 if (core_->socket_) 328 if (core_->socket_)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 DCHECK_EQ(socket_, INVALID_SOCKET); 361 DCHECK_EQ(socket_, INVALID_SOCKET);
348 362
349 int error = SetupSocket(socket); 363 int error = SetupSocket(socket);
350 if (error) 364 if (error)
351 return MapSystemError(error); 365 return MapSystemError(error);
352 366
353 socket_ = socket; 367 socket_ = socket;
354 SetNonBlocking(socket_); 368 SetNonBlocking(socket_);
355 369
356 core_ = new Core(this); 370 core_ = new Core(this);
357
358 current_address_index_ = 0; 371 current_address_index_ = 0;
359 use_history_.set_was_ever_connected(); 372 use_history_.set_was_ever_connected();
360 373
361 return OK; 374 return OK;
362 } 375 }
363 376
364 int TCPClientSocketWin::Bind(const IPEndPoint& address) { 377 int TCPClientSocketWin::Bind(const IPEndPoint& address) {
365 if (current_address_index_ >= 0 || bind_address_.get()) { 378 if (current_address_index_ >= 0 || bind_address_.get()) {
366 // Cannot bind the socket if we are already connected or connecting. 379 // Cannot bind the socket if we are already connected or connecting.
367 return ERR_UNEXPECTED; 380 return ERR_UNEXPECTED;
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 717
705 int TCPClientSocketWin::Read(IOBuffer* buf, 718 int TCPClientSocketWin::Read(IOBuffer* buf,
706 int buf_len, 719 int buf_len,
707 const CompletionCallback& callback) { 720 const CompletionCallback& callback) {
708 DCHECK(CalledOnValidThread()); 721 DCHECK(CalledOnValidThread());
709 DCHECK_NE(socket_, INVALID_SOCKET); 722 DCHECK_NE(socket_, INVALID_SOCKET);
710 DCHECK(!waiting_read_); 723 DCHECK(!waiting_read_);
711 DCHECK(read_callback_.is_null()); 724 DCHECK(read_callback_.is_null());
712 DCHECK(!core_->read_iobuffer_); 725 DCHECK(!core_->read_iobuffer_);
713 726
714 buf_len = core_->ThrottleReadSize(buf_len); 727 int rv = DoRead(buf, buf_len, callback);
715 728
716 WSABUF read_buffer; 729 return rv;
slamm 2012/10/25 19:51:48 Drop rv? return DoRead(buf, buf_len, callback);
pmeenan 2012/10/26 14:03:49 Done. Wasn't sure if convention allowed for retur
717 read_buffer.len = buf_len;
718 read_buffer.buf = buf->data();
719
720 // TODO(wtc): Remove the assertion after enough testing.
721 AssertEventNotSignaled(core_->read_overlapped_.hEvent);
722 DWORD num, flags = 0;
723 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags,
724 &core_->read_overlapped_, NULL);
725 if (rv == 0) {
726 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
727 base::StatsCounter read_bytes("tcp.read_bytes");
728 read_bytes.Add(num);
729 num_bytes_read_ += num;
730 if (num > 0)
731 use_history_.set_was_used_to_convey_data();
732 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num,
733 buf->data());
734 return static_cast<int>(num);
735 }
736 } else {
737 int os_error = WSAGetLastError();
738 if (os_error != WSA_IO_PENDING) {
739 int net_error = MapSystemError(os_error);
740 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
741 CreateNetLogSocketErrorCallback(net_error, os_error));
742 return net_error;
743 }
744 }
745 core_->WatchForRead();
746 waiting_read_ = true;
747 read_callback_ = callback;
748 core_->read_iobuffer_ = buf;
749 return ERR_IO_PENDING;
750 } 730 }
751 731
752 int TCPClientSocketWin::Write(IOBuffer* buf, 732 int TCPClientSocketWin::Write(IOBuffer* buf,
753 int buf_len, 733 int buf_len,
754 const CompletionCallback& callback) { 734 const CompletionCallback& callback) {
755 DCHECK(CalledOnValidThread()); 735 DCHECK(CalledOnValidThread());
756 DCHECK_NE(socket_, INVALID_SOCKET); 736 DCHECK_NE(socket_, INVALID_SOCKET);
757 DCHECK(!waiting_write_); 737 DCHECK(!waiting_write_);
758 DCHECK(write_callback_.is_null()); 738 DCHECK(write_callback_.is_null());
759 DCHECK_GT(buf_len, 0); 739 DCHECK_GT(buf_len, 0);
760 DCHECK(!core_->write_iobuffer_); 740 DCHECK(!core_->write_iobuffer_);
761 741
762 base::StatsCounter writes("tcp.writes"); 742 base::StatsCounter writes("tcp.writes");
763 writes.Increment(); 743 writes.Increment();
764 744
765 WSABUF write_buffer; 745 WSABUF write_buffer;
766 write_buffer.len = buf_len; 746 write_buffer.len = buf_len;
767 write_buffer.buf = buf->data(); 747 write_buffer.buf = buf->data();
768 core_->write_buffer_length_ = buf_len;
769 748
770 // TODO(wtc): Remove the assertion after enough testing. 749 // TODO(wtc): Remove the assertion after enough testing.
771 AssertEventNotSignaled(core_->write_overlapped_.hEvent); 750 AssertEventNotSignaled(core_->write_overlapped_.hEvent);
772 DWORD num; 751 DWORD num;
773 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, 752 int rv = WSASend(socket_, &write_buffer, 1, &num, 0,
774 &core_->write_overlapped_, NULL); 753 &core_->write_overlapped_, NULL);
775 if (rv == 0) { 754 if (rv == 0) {
776 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { 755 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) {
777 rv = static_cast<int>(num); 756 rv = static_cast<int>(num);
778 if (rv > buf_len || rv < 0) { 757 if (rv > buf_len || rv < 0) {
(...skipping 13 matching lines...) Expand all
792 } 771 }
793 } else { 772 } else {
794 int os_error = WSAGetLastError(); 773 int os_error = WSAGetLastError();
795 if (os_error != WSA_IO_PENDING) { 774 if (os_error != WSA_IO_PENDING) {
796 int net_error = MapSystemError(os_error); 775 int net_error = MapSystemError(os_error);
797 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, 776 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR,
798 CreateNetLogSocketErrorCallback(net_error, os_error)); 777 CreateNetLogSocketErrorCallback(net_error, os_error));
799 return net_error; 778 return net_error;
800 } 779 }
801 } 780 }
802 core_->WatchForWrite();
803 waiting_write_ = true; 781 waiting_write_ = true;
804 write_callback_ = callback; 782 write_callback_ = callback;
805 core_->write_iobuffer_ = buf; 783 core_->write_iobuffer_ = buf;
784 core_->write_buffer_length_ = buf_len;
785 core_->WatchForWrite();
806 return ERR_IO_PENDING; 786 return ERR_IO_PENDING;
807 } 787 }
808 788
809 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { 789 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) {
810 DCHECK(CalledOnValidThread()); 790 DCHECK(CalledOnValidThread());
811 return SetSocketReceiveBufferSize(socket_, size); 791 return SetSocketReceiveBufferSize(socket_, size);
812 } 792 }
813 793
814 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { 794 bool TCPClientSocketWin::SetSendBufferSize(int32 size) {
815 DCHECK(CalledOnValidThread()); 795 DCHECK(CalledOnValidThread());
816 return SetSocketSendBufferSize(socket_, size); 796 return SetSocketSendBufferSize(socket_, size);
817 } 797 }
818 798
819 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) { 799 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) {
820 return SetTCPKeepAlive(socket_, enable, delay); 800 return SetTCPKeepAlive(socket_, enable, delay);
821 } 801 }
822 802
823 bool TCPClientSocketWin::SetNoDelay(bool no_delay) { 803 bool TCPClientSocketWin::SetNoDelay(bool no_delay) {
824 return DisableNagle(socket_, no_delay); 804 return DisableNagle(socket_, no_delay);
825 } 805 }
826 806
807 void TCPClientSocketWin::DisableOverlappedReads() {
808 g_disable_overlapped_reads = true;
809 }
810
827 void TCPClientSocketWin::LogConnectCompletion(int net_error) { 811 void TCPClientSocketWin::LogConnectCompletion(int net_error) {
828 if (net_error == OK) 812 if (net_error == OK)
829 UpdateConnectionTypeHistograms(CONNECTION_ANY); 813 UpdateConnectionTypeHistograms(CONNECTION_ANY);
830 814
831 if (net_error != OK) { 815 if (net_error != OK) {
832 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); 816 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error);
833 return; 817 return;
834 } 818 }
835 819
836 struct sockaddr_storage source_address; 820 struct sockaddr_storage source_address;
837 socklen_t addrlen = sizeof(source_address); 821 socklen_t addrlen = sizeof(source_address);
838 int rv = getsockname( 822 int rv = getsockname(
839 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); 823 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen);
840 if (rv != 0) { 824 if (rv != 0) {
841 LOG(ERROR) << "getsockname() [rv: " << rv 825 LOG(ERROR) << "getsockname() [rv: " << rv
842 << "] error: " << WSAGetLastError(); 826 << "] error: " << WSAGetLastError();
843 NOTREACHED(); 827 NOTREACHED();
844 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); 828 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv);
845 return; 829 return;
846 } 830 }
847 831
848 net_log_.EndEvent( 832 net_log_.EndEvent(
849 NetLog::TYPE_TCP_CONNECT, 833 NetLog::TYPE_TCP_CONNECT,
850 CreateNetLogSourceAddressCallback( 834 CreateNetLogSourceAddressCallback(
851 reinterpret_cast<const struct sockaddr*>(&source_address), 835 reinterpret_cast<const struct sockaddr*>(&source_address),
852 sizeof(source_address))); 836 sizeof(source_address)));
853 } 837 }
854 838
839 int TCPClientSocketWin::DoRead(IOBuffer* buf, int buf_len,
840 const CompletionCallback& callback) {
841 if (core_->disable_overlapped_reads_) {
842 if (!core_->non_blocking_reads_initialized_) {
843 WSAEventSelect(socket_, core_->read_overlapped_.hEvent,
844 FD_READ | FD_CLOSE);
845 core_->non_blocking_reads_initialized_ = true;
846 }
847 int rv = recv(socket_, buf->data(), buf_len, 0);
848 if (rv == SOCKET_ERROR) {
849 int os_error = WSAGetLastError();
850 if (os_error != WSAEWOULDBLOCK) {
851 int net_error = MapSystemError(os_error);
852 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
853 CreateNetLogSocketErrorCallback(net_error, os_error));
854 return net_error;
855 }
856 } else {
857 base::StatsCounter read_bytes("tcp.read_bytes");
858 if (rv > 0) {
859 use_history_.set_was_used_to_convey_data();
860 read_bytes.Add(rv);
861 num_bytes_read_ += rv;
862 }
863 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv,
864 buf->data());
865 return rv;
866 }
867 } else {
868 buf_len = core_->ThrottleReadSize(buf_len);
869
870 WSABUF read_buffer;
871 read_buffer.len = buf_len;
872 read_buffer.buf = buf->data();
873
874 // TODO(wtc): Remove the assertion after enough testing.
875 AssertEventNotSignaled(core_->read_overlapped_.hEvent);
876 DWORD num;
877 DWORD flags = 0;
878 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags,
879 &core_->read_overlapped_, NULL);
880 if (rv == 0) {
881 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
882 base::StatsCounter read_bytes("tcp.read_bytes");
883 if (num > 0) {
884 use_history_.set_was_used_to_convey_data();
885 read_bytes.Add(num);
886 num_bytes_read_ += num;
887 }
888 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num,
889 buf->data());
890 return static_cast<int>(num);
891 }
892 } else {
893 int os_error = WSAGetLastError();
894 if (os_error != WSA_IO_PENDING) {
895 int net_error = MapSystemError(os_error);
896 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
897 CreateNetLogSocketErrorCallback(net_error, os_error));
slamm 2012/10/25 19:51:48 Indent one more space.
pmeenan 2012/10/26 14:03:49 Had to switch to a 4-space intent instead, one mor
898 return net_error;
899 }
900 }
901 }
902
903 waiting_read_ = true;
904 read_callback_ = callback;
905 core_->read_iobuffer_ = buf;
906 core_->read_buffer_length_ = buf_len;
907 core_->WatchForRead();
908 return ERR_IO_PENDING;
909 }
910
855 void TCPClientSocketWin::DoReadCallback(int rv) { 911 void TCPClientSocketWin::DoReadCallback(int rv) {
856 DCHECK_NE(rv, ERR_IO_PENDING); 912 DCHECK_NE(rv, ERR_IO_PENDING);
857 DCHECK(!read_callback_.is_null()); 913 DCHECK(!read_callback_.is_null());
858 914
859 // Since Run may result in Read being called, clear read_callback_ up front. 915 // Since Run may result in Read being called, clear read_callback_ up front.
860 CompletionCallback c = read_callback_; 916 CompletionCallback c = read_callback_;
861 read_callback_.Reset(); 917 read_callback_.Reset();
862 c.Run(rv); 918 c.Run(rv);
863 } 919 }
864 920
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, 973 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED,
918 num_bytes, core_->read_iobuffer_->data()); 974 num_bytes, core_->read_iobuffer_->data());
919 rv = static_cast<int>(num_bytes); 975 rv = static_cast<int>(num_bytes);
920 } else { 976 } else {
921 int os_error = WSAGetLastError(); 977 int os_error = WSAGetLastError();
922 rv = MapSystemError(os_error); 978 rv = MapSystemError(os_error);
923 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, 979 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
924 CreateNetLogSocketErrorCallback(rv, os_error)); 980 CreateNetLogSocketErrorCallback(rv, os_error));
925 } 981 }
926 core_->read_iobuffer_ = NULL; 982 core_->read_iobuffer_ = NULL;
983 core_->read_buffer_length_ = 0;
927 DoReadCallback(rv); 984 DoReadCallback(rv);
928 } 985 }
929 986
930 void TCPClientSocketWin::DidCompleteWrite() { 987 void TCPClientSocketWin::DidCompleteWrite() {
931 DCHECK(waiting_write_); 988 DCHECK(waiting_write_);
932 989
933 DWORD num_bytes, flags; 990 DWORD num_bytes, flags;
934 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, 991 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_,
935 &num_bytes, FALSE, &flags); 992 &num_bytes, FALSE, &flags);
936 WSAResetEvent(core_->write_overlapped_.hEvent); 993 WSAResetEvent(core_->write_overlapped_.hEvent);
(...skipping 19 matching lines...) Expand all
956 if (num_bytes > 0) 1013 if (num_bytes > 0)
957 use_history_.set_was_used_to_convey_data(); 1014 use_history_.set_was_used_to_convey_data();
958 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, 1015 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes,
959 core_->write_iobuffer_->data()); 1016 core_->write_iobuffer_->data());
960 } 1017 }
961 } 1018 }
962 core_->write_iobuffer_ = NULL; 1019 core_->write_iobuffer_ = NULL;
963 DoWriteCallback(rv); 1020 DoWriteCallback(rv);
964 } 1021 }
965 1022
1023 void TCPClientSocketWin::DidSignalRead() {
1024 DCHECK(waiting_read_);
1025 int os_error = 0;
1026 WSANETWORKEVENTS network_events;
1027 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent,
1028 &network_events);
1029 if (rv == SOCKET_ERROR) {
1030 os_error = WSAGetLastError();
1031 rv = MapSystemError(os_error);
1032 } else {
1033 if (network_events.lNetworkEvents & FD_READ) {
slamm 2012/10/25 19:51:48 Change 1032 to "else if".
pmeenan 2012/10/26 14:03:49 Done.
1034 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_,
1035 read_callback_);
1036 if (rv == ERR_IO_PENDING)
1037 return;
1038 } else if (network_events.lNetworkEvents & FD_CLOSE) {
1039 if (network_events.iErrorCode[FD_CLOSE_BIT]) {
1040 rv = MapSystemError(network_events.iErrorCode[FD_CLOSE_BIT]);
1041 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
1042 CreateNetLogSocketErrorCallback(rv, os_error));
1043 } else {
1044 rv = 0;
1045 }
1046 } else {
1047 // This should not happen but I have seen cases where we will get
1048 // signaled but the network events flags are all clear (0).
1049 core_->WatchForRead();
1050 return;
1051 }
1052 }
1053 waiting_read_ = false;
1054 core_->read_iobuffer_ = NULL;
1055 core_->read_buffer_length_ = 0;
1056 DoReadCallback(rv);
1057 }
1058
966 } // namespace net 1059 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698