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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 22 matching lines...) Expand all Loading... |
293 AddRef(); | 303 AddRef(); |
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(); |
| 313 } else if (core_->disable_overlapped_reads_) { |
| 314 core_->socket_->DidSignalRead(); |
303 } else { | 315 } else { |
304 core_->socket_->DidCompleteRead(); | 316 core_->socket_->DidCompleteRead(); |
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) { |
(...skipping 34 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); |
357 | |
358 current_address_index_ = 0; | 369 current_address_index_ = 0; |
359 use_history_.set_was_ever_connected(); | 370 use_history_.set_was_ever_connected(); |
360 | 371 |
361 return OK; | 372 return OK; |
362 } | 373 } |
363 | 374 |
364 int TCPClientSocketWin::Bind(const IPEndPoint& address) { | 375 int TCPClientSocketWin::Bind(const IPEndPoint& address) { |
365 if (current_address_index_ >= 0 || bind_address_.get()) { | 376 if (current_address_index_ >= 0 || bind_address_.get()) { |
366 // Cannot bind the socket if we are already connected or connecting. | 377 // Cannot bind the socket if we are already connected or connecting. |
367 return ERR_UNEXPECTED; | 378 return ERR_UNEXPECTED; |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 | 715 |
705 int TCPClientSocketWin::Read(IOBuffer* buf, | 716 int TCPClientSocketWin::Read(IOBuffer* buf, |
706 int buf_len, | 717 int buf_len, |
707 const CompletionCallback& callback) { | 718 const CompletionCallback& callback) { |
708 DCHECK(CalledOnValidThread()); | 719 DCHECK(CalledOnValidThread()); |
709 DCHECK_NE(socket_, INVALID_SOCKET); | 720 DCHECK_NE(socket_, INVALID_SOCKET); |
710 DCHECK(!waiting_read_); | 721 DCHECK(!waiting_read_); |
711 DCHECK(read_callback_.is_null()); | 722 DCHECK(read_callback_.is_null()); |
712 DCHECK(!core_->read_iobuffer_); | 723 DCHECK(!core_->read_iobuffer_); |
713 | 724 |
714 buf_len = core_->ThrottleReadSize(buf_len); | 725 return DoRead(buf, buf_len, callback); |
715 | |
716 WSABUF read_buffer; | |
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 } | 726 } |
751 | 727 |
752 int TCPClientSocketWin::Write(IOBuffer* buf, | 728 int TCPClientSocketWin::Write(IOBuffer* buf, |
753 int buf_len, | 729 int buf_len, |
754 const CompletionCallback& callback) { | 730 const CompletionCallback& callback) { |
755 DCHECK(CalledOnValidThread()); | 731 DCHECK(CalledOnValidThread()); |
756 DCHECK_NE(socket_, INVALID_SOCKET); | 732 DCHECK_NE(socket_, INVALID_SOCKET); |
757 DCHECK(!waiting_write_); | 733 DCHECK(!waiting_write_); |
758 DCHECK(write_callback_.is_null()); | 734 DCHECK(write_callback_.is_null()); |
759 DCHECK_GT(buf_len, 0); | 735 DCHECK_GT(buf_len, 0); |
760 DCHECK(!core_->write_iobuffer_); | 736 DCHECK(!core_->write_iobuffer_); |
761 | 737 |
762 base::StatsCounter writes("tcp.writes"); | 738 base::StatsCounter writes("tcp.writes"); |
763 writes.Increment(); | 739 writes.Increment(); |
764 | 740 |
765 WSABUF write_buffer; | 741 WSABUF write_buffer; |
766 write_buffer.len = buf_len; | 742 write_buffer.len = buf_len; |
767 write_buffer.buf = buf->data(); | 743 write_buffer.buf = buf->data(); |
768 core_->write_buffer_length_ = buf_len; | |
769 | 744 |
770 // TODO(wtc): Remove the assertion after enough testing. | 745 // TODO(wtc): Remove the assertion after enough testing. |
771 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 746 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
772 DWORD num; | 747 DWORD num; |
773 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, | 748 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, |
774 &core_->write_overlapped_, NULL); | 749 &core_->write_overlapped_, NULL); |
775 if (rv == 0) { | 750 if (rv == 0) { |
776 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 751 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
777 rv = static_cast<int>(num); | 752 rv = static_cast<int>(num); |
778 if (rv > buf_len || rv < 0) { | 753 if (rv > buf_len || rv < 0) { |
(...skipping 13 matching lines...) Expand all Loading... |
792 } | 767 } |
793 } else { | 768 } else { |
794 int os_error = WSAGetLastError(); | 769 int os_error = WSAGetLastError(); |
795 if (os_error != WSA_IO_PENDING) { | 770 if (os_error != WSA_IO_PENDING) { |
796 int net_error = MapSystemError(os_error); | 771 int net_error = MapSystemError(os_error); |
797 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 772 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
798 CreateNetLogSocketErrorCallback(net_error, os_error)); | 773 CreateNetLogSocketErrorCallback(net_error, os_error)); |
799 return net_error; | 774 return net_error; |
800 } | 775 } |
801 } | 776 } |
802 core_->WatchForWrite(); | |
803 waiting_write_ = true; | 777 waiting_write_ = true; |
804 write_callback_ = callback; | 778 write_callback_ = callback; |
805 core_->write_iobuffer_ = buf; | 779 core_->write_iobuffer_ = buf; |
| 780 core_->write_buffer_length_ = buf_len; |
| 781 core_->WatchForWrite(); |
806 return ERR_IO_PENDING; | 782 return ERR_IO_PENDING; |
807 } | 783 } |
808 | 784 |
809 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { | 785 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { |
810 DCHECK(CalledOnValidThread()); | 786 DCHECK(CalledOnValidThread()); |
811 return SetSocketReceiveBufferSize(socket_, size); | 787 return SetSocketReceiveBufferSize(socket_, size); |
812 } | 788 } |
813 | 789 |
814 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { | 790 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { |
815 DCHECK(CalledOnValidThread()); | 791 DCHECK(CalledOnValidThread()); |
816 return SetSocketSendBufferSize(socket_, size); | 792 return SetSocketSendBufferSize(socket_, size); |
817 } | 793 } |
818 | 794 |
819 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) { | 795 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) { |
820 return SetTCPKeepAlive(socket_, enable, delay); | 796 return SetTCPKeepAlive(socket_, enable, delay); |
821 } | 797 } |
822 | 798 |
823 bool TCPClientSocketWin::SetNoDelay(bool no_delay) { | 799 bool TCPClientSocketWin::SetNoDelay(bool no_delay) { |
824 return DisableNagle(socket_, no_delay); | 800 return DisableNagle(socket_, no_delay); |
825 } | 801 } |
826 | 802 |
| 803 void TCPClientSocketWin::DisableOverlappedReads() { |
| 804 g_disable_overlapped_reads = true; |
| 805 } |
| 806 |
827 void TCPClientSocketWin::LogConnectCompletion(int net_error) { | 807 void TCPClientSocketWin::LogConnectCompletion(int net_error) { |
828 if (net_error == OK) | 808 if (net_error == OK) |
829 UpdateConnectionTypeHistograms(CONNECTION_ANY); | 809 UpdateConnectionTypeHistograms(CONNECTION_ANY); |
830 | 810 |
831 if (net_error != OK) { | 811 if (net_error != OK) { |
832 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); | 812 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); |
833 return; | 813 return; |
834 } | 814 } |
835 | 815 |
836 struct sockaddr_storage source_address; | 816 struct sockaddr_storage source_address; |
837 socklen_t addrlen = sizeof(source_address); | 817 socklen_t addrlen = sizeof(source_address); |
838 int rv = getsockname( | 818 int rv = getsockname( |
839 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); | 819 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); |
840 if (rv != 0) { | 820 if (rv != 0) { |
841 LOG(ERROR) << "getsockname() [rv: " << rv | 821 LOG(ERROR) << "getsockname() [rv: " << rv |
842 << "] error: " << WSAGetLastError(); | 822 << "] error: " << WSAGetLastError(); |
843 NOTREACHED(); | 823 NOTREACHED(); |
844 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); | 824 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); |
845 return; | 825 return; |
846 } | 826 } |
847 | 827 |
848 net_log_.EndEvent( | 828 net_log_.EndEvent( |
849 NetLog::TYPE_TCP_CONNECT, | 829 NetLog::TYPE_TCP_CONNECT, |
850 CreateNetLogSourceAddressCallback( | 830 CreateNetLogSourceAddressCallback( |
851 reinterpret_cast<const struct sockaddr*>(&source_address), | 831 reinterpret_cast<const struct sockaddr*>(&source_address), |
852 sizeof(source_address))); | 832 sizeof(source_address))); |
853 } | 833 } |
854 | 834 |
| 835 int TCPClientSocketWin::DoRead(IOBuffer* buf, int buf_len, |
| 836 const CompletionCallback& callback) { |
| 837 if (core_->disable_overlapped_reads_) { |
| 838 if (!core_->non_blocking_reads_initialized_) { |
| 839 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, |
| 840 FD_READ | FD_CLOSE); |
| 841 core_->non_blocking_reads_initialized_ = true; |
| 842 } |
| 843 int rv = recv(socket_, buf->data(), buf_len, 0); |
| 844 if (rv == SOCKET_ERROR) { |
| 845 int os_error = WSAGetLastError(); |
| 846 if (os_error != WSAEWOULDBLOCK) { |
| 847 int net_error = MapSystemError(os_error); |
| 848 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 849 CreateNetLogSocketErrorCallback(net_error, os_error)); |
| 850 return net_error; |
| 851 } |
| 852 } else { |
| 853 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 854 if (rv > 0) { |
| 855 use_history_.set_was_used_to_convey_data(); |
| 856 read_bytes.Add(rv); |
| 857 num_bytes_read_ += rv; |
| 858 } |
| 859 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, |
| 860 buf->data()); |
| 861 return rv; |
| 862 } |
| 863 } else { |
| 864 buf_len = core_->ThrottleReadSize(buf_len); |
| 865 |
| 866 WSABUF read_buffer; |
| 867 read_buffer.len = buf_len; |
| 868 read_buffer.buf = buf->data(); |
| 869 |
| 870 // TODO(wtc): Remove the assertion after enough testing. |
| 871 AssertEventNotSignaled(core_->read_overlapped_.hEvent); |
| 872 DWORD num; |
| 873 DWORD flags = 0; |
| 874 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags, |
| 875 &core_->read_overlapped_, NULL); |
| 876 if (rv == 0) { |
| 877 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
| 878 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 879 if (num > 0) { |
| 880 use_history_.set_was_used_to_convey_data(); |
| 881 read_bytes.Add(num); |
| 882 num_bytes_read_ += num; |
| 883 } |
| 884 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, |
| 885 buf->data()); |
| 886 return static_cast<int>(num); |
| 887 } |
| 888 } else { |
| 889 int os_error = WSAGetLastError(); |
| 890 if (os_error != WSA_IO_PENDING) { |
| 891 int net_error = MapSystemError(os_error); |
| 892 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 893 CreateNetLogSocketErrorCallback(net_error, os_error)); |
| 894 return net_error; |
| 895 } |
| 896 } |
| 897 } |
| 898 |
| 899 waiting_read_ = true; |
| 900 read_callback_ = callback; |
| 901 core_->read_iobuffer_ = buf; |
| 902 core_->read_buffer_length_ = buf_len; |
| 903 core_->WatchForRead(); |
| 904 return ERR_IO_PENDING; |
| 905 } |
| 906 |
855 void TCPClientSocketWin::DoReadCallback(int rv) { | 907 void TCPClientSocketWin::DoReadCallback(int rv) { |
856 DCHECK_NE(rv, ERR_IO_PENDING); | 908 DCHECK_NE(rv, ERR_IO_PENDING); |
857 DCHECK(!read_callback_.is_null()); | 909 DCHECK(!read_callback_.is_null()); |
858 | 910 |
859 // Since Run may result in Read being called, clear read_callback_ up front. | 911 // Since Run may result in Read being called, clear read_callback_ up front. |
860 CompletionCallback c = read_callback_; | 912 CompletionCallback c = read_callback_; |
861 read_callback_.Reset(); | 913 read_callback_.Reset(); |
862 c.Run(rv); | 914 c.Run(rv); |
863 } | 915 } |
864 | 916 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 969 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
918 num_bytes, core_->read_iobuffer_->data()); | 970 num_bytes, core_->read_iobuffer_->data()); |
919 rv = static_cast<int>(num_bytes); | 971 rv = static_cast<int>(num_bytes); |
920 } else { | 972 } else { |
921 int os_error = WSAGetLastError(); | 973 int os_error = WSAGetLastError(); |
922 rv = MapSystemError(os_error); | 974 rv = MapSystemError(os_error); |
923 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 975 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
924 CreateNetLogSocketErrorCallback(rv, os_error)); | 976 CreateNetLogSocketErrorCallback(rv, os_error)); |
925 } | 977 } |
926 core_->read_iobuffer_ = NULL; | 978 core_->read_iobuffer_ = NULL; |
| 979 core_->read_buffer_length_ = 0; |
927 DoReadCallback(rv); | 980 DoReadCallback(rv); |
928 } | 981 } |
929 | 982 |
930 void TCPClientSocketWin::DidCompleteWrite() { | 983 void TCPClientSocketWin::DidCompleteWrite() { |
931 DCHECK(waiting_write_); | 984 DCHECK(waiting_write_); |
932 | 985 |
933 DWORD num_bytes, flags; | 986 DWORD num_bytes, flags; |
934 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 987 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
935 &num_bytes, FALSE, &flags); | 988 &num_bytes, FALSE, &flags); |
936 WSAResetEvent(core_->write_overlapped_.hEvent); | 989 WSAResetEvent(core_->write_overlapped_.hEvent); |
(...skipping 19 matching lines...) Expand all Loading... |
956 if (num_bytes > 0) | 1009 if (num_bytes > 0) |
957 use_history_.set_was_used_to_convey_data(); | 1010 use_history_.set_was_used_to_convey_data(); |
958 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, | 1011 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, |
959 core_->write_iobuffer_->data()); | 1012 core_->write_iobuffer_->data()); |
960 } | 1013 } |
961 } | 1014 } |
962 core_->write_iobuffer_ = NULL; | 1015 core_->write_iobuffer_ = NULL; |
963 DoWriteCallback(rv); | 1016 DoWriteCallback(rv); |
964 } | 1017 } |
965 | 1018 |
| 1019 void TCPClientSocketWin::DidSignalRead() { |
| 1020 DCHECK(waiting_read_); |
| 1021 int os_error = 0; |
| 1022 WSANETWORKEVENTS network_events; |
| 1023 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, |
| 1024 &network_events); |
| 1025 if (rv == SOCKET_ERROR) { |
| 1026 os_error = WSAGetLastError(); |
| 1027 rv = MapSystemError(os_error); |
| 1028 } else if (network_events.lNetworkEvents & FD_READ) { |
| 1029 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_, |
| 1030 read_callback_); |
| 1031 if (rv == ERR_IO_PENDING) |
| 1032 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)); |
| 1038 } else { |
| 1039 rv = 0; |
| 1040 } |
| 1041 } else { |
| 1042 // This should not happen but I have seen cases where we will get |
| 1043 // signaled but the network events flags are all clear (0). |
| 1044 core_->WatchForRead(); |
| 1045 return; |
| 1046 } |
| 1047 waiting_read_ = false; |
| 1048 core_->read_iobuffer_ = NULL; |
| 1049 core_->read_buffer_length_ = 0; |
| 1050 DoReadCallback(rv); |
| 1051 } |
| 1052 |
966 } // namespace net | 1053 } // namespace net |
OLD | NEW |