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 10 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |