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

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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 185
185 // The separate OVERLAPPED variables for asynchronous operation. 186 // The separate OVERLAPPED variables for asynchronous operation.
186 // |read_overlapped_| is used for both Connect() and Read(). 187 // |read_overlapped_| is used for both Connect() and Read().
187 // |write_overlapped_| is only used for Write(); 188 // |write_overlapped_| is only used for Write();
188 OVERLAPPED read_overlapped_; 189 OVERLAPPED read_overlapped_;
189 OVERLAPPED write_overlapped_; 190 OVERLAPPED write_overlapped_;
190 191
191 // The buffers used in Read() and Write(). 192 // The buffers used in Read() and Write().
192 scoped_refptr<IOBuffer> read_iobuffer_; 193 scoped_refptr<IOBuffer> read_iobuffer_;
193 scoped_refptr<IOBuffer> write_iobuffer_; 194 scoped_refptr<IOBuffer> write_iobuffer_;
195 int read_buffer_length_;
194 int write_buffer_length_; 196 int write_buffer_length_;
195 197
196 // Throttle the read size based on our current slow start state. 198 // Throttle the read size based on our current slow start state.
197 // Returns the throttled read size. 199 // Returns the throttled read size.
198 int ThrottleReadSize(int size) { 200 int ThrottleReadSize(int size) {
199 if (slow_start_throttle_ < kMaxSlowStartThrottle) { 201 if (slow_start_throttle_ < kMaxSlowStartThrottle) {
200 size = std::min(size, slow_start_throttle_); 202 size = std::min(size, slow_start_throttle_);
201 slow_start_throttle_ *= 2; 203 slow_start_throttle_ *= 2;
202 } 204 }
203 return size; 205 return size;
204 } 206 }
wtc 2012/10/18 23:17:10 Could you move the ThrottleReadSize() method up to
pmeenan 2012/10/19 20:49:41 Done.
205 207
208 // Remember the state of overlapped reads for the duration of the socket
wtc 2012/10/18 23:17:10 Nit: overlapped reads => g_disable_overlapped_read
pmeenan 2012/10/19 20:49:41 Done.
209 // based on what it was when the socket was created.
210 bool disable_overlapped_reads_;
211
206 private: 212 private:
207 friend class base::RefCounted<Core>; 213 friend class base::RefCounted<Core>;
208 214
209 class ReadDelegate : public base::win::ObjectWatcher::Delegate { 215 class ReadDelegate : public base::win::ObjectWatcher::Delegate {
210 public: 216 public:
211 explicit ReadDelegate(Core* core) : core_(core) {} 217 explicit ReadDelegate(Core* core) : core_(core) {}
212 virtual ~ReadDelegate() {} 218 virtual ~ReadDelegate() {}
213 219
214 // base::ObjectWatcher::Delegate methods: 220 // base::ObjectWatcher::Delegate methods:
215 virtual void OnObjectSignaled(HANDLE object); 221 virtual void OnObjectSignaled(HANDLE object);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 static const int kInitialSlowStartThrottle = 1 * 1024; 257 static const int kInitialSlowStartThrottle = 1 * 1024;
252 static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle; 258 static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle;
253 int slow_start_throttle_; 259 int slow_start_throttle_;
254 260
255 DISALLOW_COPY_AND_ASSIGN(Core); 261 DISALLOW_COPY_AND_ASSIGN(Core);
256 }; 262 };
257 263
258 TCPClientSocketWin::Core::Core( 264 TCPClientSocketWin::Core::Core(
259 TCPClientSocketWin* socket) 265 TCPClientSocketWin* socket)
260 : write_buffer_length_(0), 266 : write_buffer_length_(0),
267 read_buffer_length_(0),
268 disable_overlapped_reads_(g_disable_overlapped_reads),
261 socket_(socket), 269 socket_(socket),
262 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), 270 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)),
263 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)), 271 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)),
264 slow_start_throttle_(kInitialSlowStartThrottle) { 272 slow_start_throttle_(kInitialSlowStartThrottle) {
265 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); 273 memset(&read_overlapped_, 0, sizeof(read_overlapped_));
266 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); 274 memset(&write_overlapped_, 0, sizeof(write_overlapped_));
267 275
268 read_overlapped_.hEvent = WSACreateEvent(); 276 read_overlapped_.hEvent = WSACreateEvent();
269 write_overlapped_.hEvent = WSACreateEvent(); 277 write_overlapped_.hEvent = WSACreateEvent();
270 } 278 }
(...skipping 22 matching lines...) Expand all
293 AddRef(); 301 AddRef();
294 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_); 302 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_);
295 } 303 }
296 304
297 void TCPClientSocketWin::Core::ReadDelegate::OnObjectSignaled( 305 void TCPClientSocketWin::Core::ReadDelegate::OnObjectSignaled(
298 HANDLE object) { 306 HANDLE object) {
299 DCHECK_EQ(object, core_->read_overlapped_.hEvent); 307 DCHECK_EQ(object, core_->read_overlapped_.hEvent);
300 if (core_->socket_) { 308 if (core_->socket_) {
301 if (core_->socket_->waiting_connect()) { 309 if (core_->socket_->waiting_connect()) {
302 core_->socket_->DidCompleteConnect(); 310 core_->socket_->DidCompleteConnect();
303 } else { 311 } else if(core_->socket_->waiting_read_) {
wtc 2012/10/18 23:17:10 Why is it necessary to test core_->socket_->waitin
pmeenan 2012/10/19 20:49:41 Done.
304 core_->socket_->DidCompleteRead(); 312 if (core_->disable_overlapped_reads_) {
313 core_->socket_->DidSignalRead();
314 } else {
315 core_->socket_->DidCompleteRead();
316 }
305 } 317 }
306 } 318 }
307 319
308 core_->Release(); 320 core_->Release();
309 } 321 }
310 322
311 void TCPClientSocketWin::Core::WriteDelegate::OnObjectSignaled( 323 void TCPClientSocketWin::Core::WriteDelegate::OnObjectSignaled(
312 HANDLE object) { 324 HANDLE object) {
313 DCHECK_EQ(object, core_->write_overlapped_.hEvent); 325 DCHECK_EQ(object, core_->write_overlapped_.hEvent);
314 if (core_->socket_) 326 if (core_->socket_)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 DCHECK_EQ(socket_, INVALID_SOCKET); 359 DCHECK_EQ(socket_, INVALID_SOCKET);
348 360
349 int error = SetupSocket(socket); 361 int error = SetupSocket(socket);
350 if (error) 362 if (error)
351 return MapSystemError(error); 363 return MapSystemError(error);
352 364
353 socket_ = socket; 365 socket_ = socket;
354 SetNonBlocking(socket_); 366 SetNonBlocking(socket_);
355 367
356 core_ = new Core(this); 368 core_ = new Core(this);
369 if (core_->disable_overlapped_reads_) {
370 WSAEventSelect(socket_, core_->read_overlapped_.hEvent,
371 FD_READ | FD_CLOSE);
372 }
wtc 2012/10/18 23:17:10 I think we should wait until the first Read() call
pmeenan 2012/10/19 20:49:41 Done.
357 373
358 current_address_index_ = 0; 374 current_address_index_ = 0;
359 use_history_.set_was_ever_connected(); 375 use_history_.set_was_ever_connected();
360 376
361 return OK; 377 return OK;
362 } 378 }
363 379
364 int TCPClientSocketWin::Bind(const IPEndPoint& address) { 380 int TCPClientSocketWin::Bind(const IPEndPoint& address) {
365 if (current_address_index_ >= 0 || bind_address_.get()) { 381 if (current_address_index_ >= 0 || bind_address_.get()) {
366 // Cannot bind the socket if we are already connected or connecting. 382 // Cannot bind the socket if we are already connected or connecting.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 return ERR_INVALID_ARGUMENT; 494 return ERR_INVALID_ARGUMENT;
479 if (bind(socket_, storage.addr, storage.addr_len)) 495 if (bind(socket_, storage.addr, storage.addr_len))
480 return MapSystemError(errno); 496 return MapSystemError(errno);
481 } 497 }
482 } 498 }
483 499
484 DCHECK(!core_); 500 DCHECK(!core_);
485 core_ = new Core(this); 501 core_ = new Core(this);
486 // WSAEventSelect sets the socket to non-blocking mode as a side effect. 502 // WSAEventSelect sets the socket to non-blocking mode as a side effect.
487 // Our connect() and recv() calls require that the socket be non-blocking. 503 // Our connect() and recv() calls require that the socket be non-blocking.
488 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); 504 if (core_->disable_overlapped_reads_) {
505 WSAEventSelect(socket_, core_->read_overlapped_.hEvent,
506 FD_CONNECT | FD_READ | FD_CLOSE);
wtc 2012/10/18 23:17:10 I think we should wait until the first Read() call
pmeenan 2012/10/19 20:49:41 Done.
507 } else {
508 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT);
509 }
489 510
490 SockaddrStorage storage; 511 SockaddrStorage storage;
491 if (!endpoint.ToSockAddr(storage.addr, &storage.addr_len)) 512 if (!endpoint.ToSockAddr(storage.addr, &storage.addr_len))
492 return ERR_INVALID_ARGUMENT; 513 return ERR_INVALID_ARGUMENT;
493 connect_start_time_ = base::TimeTicks::Now(); 514 connect_start_time_ = base::TimeTicks::Now();
494 if (!connect(socket_, storage.addr, storage.addr_len)) { 515 if (!connect(socket_, storage.addr, storage.addr_len)) {
495 // Connected without waiting! 516 // Connected without waiting!
496 // 517 //
497 // The MSDN page for connect says: 518 // The MSDN page for connect says:
498 // With a nonblocking socket, the connection attempt cannot be completed 519 // With a nonblocking socket, the connection attempt cannot be completed
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 725
705 int TCPClientSocketWin::Read(IOBuffer* buf, 726 int TCPClientSocketWin::Read(IOBuffer* buf,
706 int buf_len, 727 int buf_len,
707 const CompletionCallback& callback) { 728 const CompletionCallback& callback) {
708 DCHECK(CalledOnValidThread()); 729 DCHECK(CalledOnValidThread());
709 DCHECK_NE(socket_, INVALID_SOCKET); 730 DCHECK_NE(socket_, INVALID_SOCKET);
710 DCHECK(!waiting_read_); 731 DCHECK(!waiting_read_);
711 DCHECK(read_callback_.is_null()); 732 DCHECK(read_callback_.is_null());
712 DCHECK(!core_->read_iobuffer_); 733 DCHECK(!core_->read_iobuffer_);
713 734
714 buf_len = core_->ThrottleReadSize(buf_len); 735 if (core_->disable_overlapped_reads_) {
715 736 int flags = 0;
wtc 2012/10/18 23:17:10 Nit: just pass 0 to recv().
pmeenan 2012/10/19 20:49:41 Done.
716 WSABUF read_buffer; 737 int rv = recv(socket_, buf->data(), buf_len, flags);
717 read_buffer.len = buf_len; 738 if (rv == SOCKET_ERROR) {
718 read_buffer.buf = buf->data(); 739 int os_error = WSAGetLastError();
719 740 if (os_error != WSAEWOULDBLOCK) {
720 // TODO(wtc): Remove the assertion after enough testing. 741 int net_error = MapSystemError(os_error);
721 AssertEventNotSignaled(core_->read_overlapped_.hEvent); 742 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
722 DWORD num, flags = 0; 743 CreateNetLogSocketErrorCallback(net_error, os_error));
723 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags, 744 return net_error;
724 &core_->read_overlapped_, NULL); 745 }
725 if (rv == 0) { 746 } else {
726 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
727 base::StatsCounter read_bytes("tcp.read_bytes"); 747 base::StatsCounter read_bytes("tcp.read_bytes");
728 read_bytes.Add(num); 748 if (rv > 0) {
729 num_bytes_read_ += num;
730 if (num > 0)
731 use_history_.set_was_used_to_convey_data(); 749 use_history_.set_was_used_to_convey_data();
732 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, 750 read_bytes.Add(rv);
751 num_bytes_read_ += rv;
752 }
753 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv,
733 buf->data()); 754 buf->data());
734 return static_cast<int>(num); 755 return rv;
735 } 756 }
736 } else { 757 } else {
737 int os_error = WSAGetLastError(); 758 buf_len = core_->ThrottleReadSize(buf_len);
738 if (os_error != WSA_IO_PENDING) { 759
739 int net_error = MapSystemError(os_error); 760 WSABUF read_buffer;
740 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, 761 read_buffer.len = buf_len;
741 CreateNetLogSocketErrorCallback(net_error, os_error)); 762 read_buffer.buf = buf->data();
742 return net_error; 763
764 // TODO(wtc): Remove the assertion after enough testing.
765 AssertEventNotSignaled(core_->read_overlapped_.hEvent);
766 DWORD num, flags = 0;
767 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags,
768 &core_->read_overlapped_, NULL);
769 if (rv == 0) {
770 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
771 base::StatsCounter read_bytes("tcp.read_bytes");
772 read_bytes.Add(num);
773 num_bytes_read_ += num;
774 if (num > 0)
775 use_history_.set_was_used_to_convey_data();
wtc 2012/10/18 23:17:10 Please make lines lines 772-775 look like lines 74
pmeenan 2012/10/19 20:49:41 Done.
776 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num,
777 buf->data());
778 return static_cast<int>(num);
779 }
780 } else {
781 int os_error = WSAGetLastError();
782 if (os_error != WSA_IO_PENDING) {
783 int net_error = MapSystemError(os_error);
784 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
785 CreateNetLogSocketErrorCallback(net_error, os_error));
786 return net_error;
787 }
743 } 788 }
744 } 789 }
745 core_->WatchForRead(); 790
746 waiting_read_ = true; 791 waiting_read_ = true;
747 read_callback_ = callback; 792 read_callback_ = callback;
748 core_->read_iobuffer_ = buf; 793 core_->read_iobuffer_ = buf;
794 core_->read_buffer_length_ = buf_len;
795 core_->WatchForRead();
wtc 2012/10/18 23:17:10 Is it important to call core_->WatchForRead() afte
pmeenan 2012/10/19 20:49:41 Sorry, wasn't 100% sure about the threading model.
749 return ERR_IO_PENDING; 796 return ERR_IO_PENDING;
750 } 797 }
751 798
752 int TCPClientSocketWin::Write(IOBuffer* buf, 799 int TCPClientSocketWin::Write(IOBuffer* buf,
753 int buf_len, 800 int buf_len,
754 const CompletionCallback& callback) { 801 const CompletionCallback& callback) {
755 DCHECK(CalledOnValidThread()); 802 DCHECK(CalledOnValidThread());
756 DCHECK_NE(socket_, INVALID_SOCKET); 803 DCHECK_NE(socket_, INVALID_SOCKET);
757 DCHECK(!waiting_write_); 804 DCHECK(!waiting_write_);
758 DCHECK(write_callback_.is_null()); 805 DCHECK(write_callback_.is_null());
759 DCHECK_GT(buf_len, 0); 806 DCHECK_GT(buf_len, 0);
760 DCHECK(!core_->write_iobuffer_); 807 DCHECK(!core_->write_iobuffer_);
761 808
762 base::StatsCounter writes("tcp.writes"); 809 base::StatsCounter writes("tcp.writes");
763 writes.Increment(); 810 writes.Increment();
764 811
765 WSABUF write_buffer; 812 WSABUF write_buffer;
766 write_buffer.len = buf_len; 813 write_buffer.len = buf_len;
767 write_buffer.buf = buf->data(); 814 write_buffer.buf = buf->data();
768 core_->write_buffer_length_ = buf_len;
769 815
770 // TODO(wtc): Remove the assertion after enough testing. 816 // TODO(wtc): Remove the assertion after enough testing.
771 AssertEventNotSignaled(core_->write_overlapped_.hEvent); 817 AssertEventNotSignaled(core_->write_overlapped_.hEvent);
772 DWORD num; 818 DWORD num;
773 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, 819 int rv = WSASend(socket_, &write_buffer, 1, &num, 0,
774 &core_->write_overlapped_, NULL); 820 &core_->write_overlapped_, NULL);
775 if (rv == 0) { 821 if (rv == 0) {
776 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { 822 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) {
777 rv = static_cast<int>(num); 823 rv = static_cast<int>(num);
778 if (rv > buf_len || rv < 0) { 824 if (rv > buf_len || rv < 0) {
(...skipping 13 matching lines...) Expand all
792 } 838 }
793 } else { 839 } else {
794 int os_error = WSAGetLastError(); 840 int os_error = WSAGetLastError();
795 if (os_error != WSA_IO_PENDING) { 841 if (os_error != WSA_IO_PENDING) {
796 int net_error = MapSystemError(os_error); 842 int net_error = MapSystemError(os_error);
797 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, 843 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR,
798 CreateNetLogSocketErrorCallback(net_error, os_error)); 844 CreateNetLogSocketErrorCallback(net_error, os_error));
799 return net_error; 845 return net_error;
800 } 846 }
801 } 847 }
802 core_->WatchForWrite();
803 waiting_write_ = true; 848 waiting_write_ = true;
804 write_callback_ = callback; 849 write_callback_ = callback;
805 core_->write_iobuffer_ = buf; 850 core_->write_iobuffer_ = buf;
851 core_->write_buffer_length_ = buf_len;
852 core_->WatchForWrite();
806 return ERR_IO_PENDING; 853 return ERR_IO_PENDING;
807 } 854 }
808 855
809 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { 856 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) {
810 DCHECK(CalledOnValidThread()); 857 DCHECK(CalledOnValidThread());
811 return SetSocketReceiveBufferSize(socket_, size); 858 return SetSocketReceiveBufferSize(socket_, size);
812 } 859 }
813 860
814 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { 861 bool TCPClientSocketWin::SetSendBufferSize(int32 size) {
815 DCHECK(CalledOnValidThread()); 862 DCHECK(CalledOnValidThread());
816 return SetSocketSendBufferSize(socket_, size); 863 return SetSocketSendBufferSize(socket_, size);
817 } 864 }
818 865
819 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) { 866 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) {
820 return SetTCPKeepAlive(socket_, enable, delay); 867 return SetTCPKeepAlive(socket_, enable, delay);
821 } 868 }
822 869
823 bool TCPClientSocketWin::SetNoDelay(bool no_delay) { 870 bool TCPClientSocketWin::SetNoDelay(bool no_delay) {
824 return DisableNagle(socket_, no_delay); 871 return DisableNagle(socket_, no_delay);
825 } 872 }
826 873
874 void TCPClientSocketWin::DisableOverlappedReads() {
875 g_disable_overlapped_reads = true;
876 }
877
827 void TCPClientSocketWin::LogConnectCompletion(int net_error) { 878 void TCPClientSocketWin::LogConnectCompletion(int net_error) {
828 if (net_error == OK) 879 if (net_error == OK)
829 UpdateConnectionTypeHistograms(CONNECTION_ANY); 880 UpdateConnectionTypeHistograms(CONNECTION_ANY);
830 881
831 if (net_error != OK) { 882 if (net_error != OK) {
832 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); 883 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error);
833 return; 884 return;
834 } 885 }
835 886
836 struct sockaddr_storage source_address; 887 struct sockaddr_storage source_address;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, 968 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED,
918 num_bytes, core_->read_iobuffer_->data()); 969 num_bytes, core_->read_iobuffer_->data());
919 rv = static_cast<int>(num_bytes); 970 rv = static_cast<int>(num_bytes);
920 } else { 971 } else {
921 int os_error = WSAGetLastError(); 972 int os_error = WSAGetLastError();
922 rv = MapSystemError(os_error); 973 rv = MapSystemError(os_error);
923 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, 974 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
924 CreateNetLogSocketErrorCallback(rv, os_error)); 975 CreateNetLogSocketErrorCallback(rv, os_error));
925 } 976 }
926 core_->read_iobuffer_ = NULL; 977 core_->read_iobuffer_ = NULL;
978 core_->read_buffer_length_ = 0;
927 DoReadCallback(rv); 979 DoReadCallback(rv);
928 } 980 }
929 981
930 void TCPClientSocketWin::DidCompleteWrite() { 982 void TCPClientSocketWin::DidCompleteWrite() {
931 DCHECK(waiting_write_); 983 DCHECK(waiting_write_);
932 984
933 DWORD num_bytes, flags; 985 DWORD num_bytes, flags;
934 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, 986 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_,
935 &num_bytes, FALSE, &flags); 987 &num_bytes, FALSE, &flags);
936 WSAResetEvent(core_->write_overlapped_.hEvent); 988 WSAResetEvent(core_->write_overlapped_.hEvent);
(...skipping 15 matching lines...) Expand all
952 rv = ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; 1004 rv = ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES;
953 } else { 1005 } else {
954 base::StatsCounter write_bytes("tcp.write_bytes"); 1006 base::StatsCounter write_bytes("tcp.write_bytes");
955 write_bytes.Add(num_bytes); 1007 write_bytes.Add(num_bytes);
956 if (num_bytes > 0) 1008 if (num_bytes > 0)
957 use_history_.set_was_used_to_convey_data(); 1009 use_history_.set_was_used_to_convey_data();
958 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, 1010 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes,
959 core_->write_iobuffer_->data()); 1011 core_->write_iobuffer_->data());
960 } 1012 }
961 } 1013 }
962 core_->write_iobuffer_ = NULL; 1014 core_->write_iobuffer_ = NULL;
wtc 2012/10/18 23:17:10 Should we also set core_->write_buffer_length_ to
963 DoWriteCallback(rv); 1015 DoWriteCallback(rv);
964 } 1016 }
965 1017
1018 void TCPClientSocketWin::DidSignalRead() {
1019 DCHECK(waiting_read_);
1020 int os_error = 0;
1021 int flags = 0;
wtc 2012/10/18 23:17:10 Just pass 0 to recv().
pmeenan 2012/10/19 20:49:41 Done.
1022 WSANETWORKEVENTS network_events;
1023 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent,
1024 &network_events);
wtc 2012/10/18 23:17:10 Align this with the first argument on the previous
pmeenan 2012/10/19 20:49:41 Done.
1025 if (rv == SOCKET_ERROR) {
1026 os_error = WSAGetLastError();
1027 rv = MapSystemError(os_error);
1028 } else {
1029 if (network_events.lNetworkEvents & FD_READ) {
1030 rv = recv(socket_, core_->read_iobuffer_->data(),
1031 core_->read_buffer_length_, flags);
1032 if (rv == SOCKET_ERROR) {
1033 os_error = WSAGetLastError();
1034 rv = MapSystemError(os_error);
wtc 2012/10/18 23:17:10 Should we check if os_error is WSAEWOULDBLOCK here
pmeenan 2012/10/19 20:49:41 Might as well for robustness. The kind of flow th
1035 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
1036 CreateNetLogSocketErrorCallback(rv, os_error));
1037 } else {
1038 base::StatsCounter read_bytes("tcp.read_bytes");
1039 if (rv > 0) {
1040 use_history_.set_was_used_to_convey_data();
1041 read_bytes.Add(rv);
1042 num_bytes_read_ += rv;
1043 }
1044 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv,
1045 core_->read_iobuffer_->data());
1046 }
1047 } else if (network_events.lNetworkEvents & FD_CLOSE) {
1048 if (network_events.iErrorCode[FD_CLOSE_BIT]) {
1049 rv = MapSystemError(network_events.iErrorCode[FD_CLOSE_BIT]);
1050 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR,
1051 CreateNetLogSocketErrorCallback(rv, os_error));
1052 } else {
1053 rv = 0;
1054 }
1055 } else {
1056 // This should not happen but I have seen cases where we will get
1057 // signaled but the network events flags are all clear (0).
wtc 2012/10/18 23:17:10 I guess this is because we receive FD_CLOSE when w
pmeenan 2012/10/19 20:49:41 I don't think so because the code at the time had
1058 core_->WatchForRead();
1059 return;
1060 }
1061 }
1062 waiting_read_ = false;
1063 core_->read_iobuffer_ = NULL;
1064 core_->read_buffer_length_ = 0;
1065 DoReadCallback(rv);
1066 }
1067
966 } // namespace net 1068 } // namespace net
OLDNEW
« net/socket/tcp_client_socket_win.h ('K') | « net/socket/tcp_client_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698