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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 : write_buffer_length_(0), |
268 read_buffer_length_(0), | |
rvargas (doing something else)
2012/10/23 00:19:40
match the declaration order.
pmeenan
2012/10/23 14:29:54
Done.
| |
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 Loading... | |
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_) { |
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 Loading... | |
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 Loading... | |
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 if (core_->disable_overlapped_reads_) { |
715 | 728 if (!core_->non_blocking_reads_initialized_) { |
716 WSABUF read_buffer; | 729 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, |
717 read_buffer.len = buf_len; | 730 FD_READ | FD_CLOSE); |
718 read_buffer.buf = buf->data(); | 731 core_->non_blocking_reads_initialized_ = true; |
719 | 732 } |
720 // TODO(wtc): Remove the assertion after enough testing. | 733 int rv = recv(socket_, buf->data(), buf_len, 0); |
721 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | 734 if (rv == SOCKET_ERROR) { |
722 DWORD num, flags = 0; | 735 int os_error = WSAGetLastError(); |
723 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags, | 736 if (os_error != WSAEWOULDBLOCK) { |
724 &core_->read_overlapped_, NULL); | 737 int net_error = MapSystemError(os_error); |
725 if (rv == 0) { | 738 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
726 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | 739 CreateNetLogSocketErrorCallback(net_error, os_error)); |
740 return net_error; | |
741 } | |
742 } else { | |
727 base::StatsCounter read_bytes("tcp.read_bytes"); | 743 base::StatsCounter read_bytes("tcp.read_bytes"); |
728 read_bytes.Add(num); | 744 if (rv > 0) { |
729 num_bytes_read_ += num; | |
730 if (num > 0) | |
731 use_history_.set_was_used_to_convey_data(); | 745 use_history_.set_was_used_to_convey_data(); |
732 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, | 746 read_bytes.Add(rv); |
747 num_bytes_read_ += rv; | |
748 } | |
749 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, | |
733 buf->data()); | 750 buf->data()); |
734 return static_cast<int>(num); | 751 return rv; |
735 } | 752 } |
736 } else { | 753 } else { |
737 int os_error = WSAGetLastError(); | 754 buf_len = core_->ThrottleReadSize(buf_len); |
738 if (os_error != WSA_IO_PENDING) { | 755 |
739 int net_error = MapSystemError(os_error); | 756 WSABUF read_buffer; |
740 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 757 read_buffer.len = buf_len; |
741 CreateNetLogSocketErrorCallback(net_error, os_error)); | 758 read_buffer.buf = buf->data(); |
742 return net_error; | 759 |
760 // TODO(wtc): Remove the assertion after enough testing. | |
761 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | |
762 DWORD num; | |
763 DWORD flags = 0; | |
764 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags, | |
765 &core_->read_overlapped_, NULL); | |
766 if (rv == 0) { | |
767 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | |
768 base::StatsCounter read_bytes("tcp.read_bytes"); | |
769 if (num > 0) { | |
770 use_history_.set_was_used_to_convey_data(); | |
771 read_bytes.Add(num); | |
772 num_bytes_read_ += num; | |
773 } | |
774 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, | |
775 buf->data()); | |
776 return static_cast<int>(num); | |
777 } | |
778 } else { | |
779 int os_error = WSAGetLastError(); | |
780 if (os_error != WSA_IO_PENDING) { | |
781 int net_error = MapSystemError(os_error); | |
782 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | |
783 CreateNetLogSocketErrorCallback(net_error, os_error)); | |
784 return net_error; | |
785 } | |
743 } | 786 } |
744 } | 787 } |
745 core_->WatchForRead(); | 788 |
746 waiting_read_ = true; | 789 waiting_read_ = true; |
747 read_callback_ = callback; | 790 read_callback_ = callback; |
748 core_->read_iobuffer_ = buf; | 791 core_->read_iobuffer_ = buf; |
792 core_->read_buffer_length_ = buf_len; | |
793 core_->WatchForRead(); | |
749 return ERR_IO_PENDING; | 794 return ERR_IO_PENDING; |
750 } | 795 } |
751 | 796 |
752 int TCPClientSocketWin::Write(IOBuffer* buf, | 797 int TCPClientSocketWin::Write(IOBuffer* buf, |
753 int buf_len, | 798 int buf_len, |
754 const CompletionCallback& callback) { | 799 const CompletionCallback& callback) { |
755 DCHECK(CalledOnValidThread()); | 800 DCHECK(CalledOnValidThread()); |
756 DCHECK_NE(socket_, INVALID_SOCKET); | 801 DCHECK_NE(socket_, INVALID_SOCKET); |
757 DCHECK(!waiting_write_); | 802 DCHECK(!waiting_write_); |
758 DCHECK(write_callback_.is_null()); | 803 DCHECK(write_callback_.is_null()); |
759 DCHECK_GT(buf_len, 0); | 804 DCHECK_GT(buf_len, 0); |
760 DCHECK(!core_->write_iobuffer_); | 805 DCHECK(!core_->write_iobuffer_); |
761 | 806 |
762 base::StatsCounter writes("tcp.writes"); | 807 base::StatsCounter writes("tcp.writes"); |
763 writes.Increment(); | 808 writes.Increment(); |
764 | 809 |
765 WSABUF write_buffer; | 810 WSABUF write_buffer; |
766 write_buffer.len = buf_len; | 811 write_buffer.len = buf_len; |
767 write_buffer.buf = buf->data(); | 812 write_buffer.buf = buf->data(); |
768 core_->write_buffer_length_ = buf_len; | |
769 | 813 |
770 // TODO(wtc): Remove the assertion after enough testing. | 814 // TODO(wtc): Remove the assertion after enough testing. |
771 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 815 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
772 DWORD num; | 816 DWORD num; |
773 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, | 817 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, |
774 &core_->write_overlapped_, NULL); | 818 &core_->write_overlapped_, NULL); |
775 if (rv == 0) { | 819 if (rv == 0) { |
776 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 820 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
777 rv = static_cast<int>(num); | 821 rv = static_cast<int>(num); |
778 if (rv > buf_len || rv < 0) { | 822 if (rv > buf_len || rv < 0) { |
(...skipping 13 matching lines...) Expand all Loading... | |
792 } | 836 } |
793 } else { | 837 } else { |
794 int os_error = WSAGetLastError(); | 838 int os_error = WSAGetLastError(); |
795 if (os_error != WSA_IO_PENDING) { | 839 if (os_error != WSA_IO_PENDING) { |
796 int net_error = MapSystemError(os_error); | 840 int net_error = MapSystemError(os_error); |
797 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 841 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
798 CreateNetLogSocketErrorCallback(net_error, os_error)); | 842 CreateNetLogSocketErrorCallback(net_error, os_error)); |
799 return net_error; | 843 return net_error; |
800 } | 844 } |
801 } | 845 } |
802 core_->WatchForWrite(); | |
803 waiting_write_ = true; | 846 waiting_write_ = true; |
804 write_callback_ = callback; | 847 write_callback_ = callback; |
805 core_->write_iobuffer_ = buf; | 848 core_->write_iobuffer_ = buf; |
849 core_->write_buffer_length_ = buf_len; | |
850 core_->WatchForWrite(); | |
806 return ERR_IO_PENDING; | 851 return ERR_IO_PENDING; |
807 } | 852 } |
808 | 853 |
809 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { | 854 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { |
810 DCHECK(CalledOnValidThread()); | 855 DCHECK(CalledOnValidThread()); |
811 return SetSocketReceiveBufferSize(socket_, size); | 856 return SetSocketReceiveBufferSize(socket_, size); |
812 } | 857 } |
813 | 858 |
814 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { | 859 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { |
815 DCHECK(CalledOnValidThread()); | 860 DCHECK(CalledOnValidThread()); |
816 return SetSocketSendBufferSize(socket_, size); | 861 return SetSocketSendBufferSize(socket_, size); |
817 } | 862 } |
818 | 863 |
819 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) { | 864 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) { |
820 return SetTCPKeepAlive(socket_, enable, delay); | 865 return SetTCPKeepAlive(socket_, enable, delay); |
821 } | 866 } |
822 | 867 |
823 bool TCPClientSocketWin::SetNoDelay(bool no_delay) { | 868 bool TCPClientSocketWin::SetNoDelay(bool no_delay) { |
824 return DisableNagle(socket_, no_delay); | 869 return DisableNagle(socket_, no_delay); |
825 } | 870 } |
826 | 871 |
872 void TCPClientSocketWin::DisableOverlappedReads() { | |
873 g_disable_overlapped_reads = true; | |
874 } | |
875 | |
827 void TCPClientSocketWin::LogConnectCompletion(int net_error) { | 876 void TCPClientSocketWin::LogConnectCompletion(int net_error) { |
828 if (net_error == OK) | 877 if (net_error == OK) |
829 UpdateConnectionTypeHistograms(CONNECTION_ANY); | 878 UpdateConnectionTypeHistograms(CONNECTION_ANY); |
830 | 879 |
831 if (net_error != OK) { | 880 if (net_error != OK) { |
832 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); | 881 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); |
833 return; | 882 return; |
834 } | 883 } |
835 | 884 |
836 struct sockaddr_storage source_address; | 885 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, | 966 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
918 num_bytes, core_->read_iobuffer_->data()); | 967 num_bytes, core_->read_iobuffer_->data()); |
919 rv = static_cast<int>(num_bytes); | 968 rv = static_cast<int>(num_bytes); |
920 } else { | 969 } else { |
921 int os_error = WSAGetLastError(); | 970 int os_error = WSAGetLastError(); |
922 rv = MapSystemError(os_error); | 971 rv = MapSystemError(os_error); |
923 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 972 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
924 CreateNetLogSocketErrorCallback(rv, os_error)); | 973 CreateNetLogSocketErrorCallback(rv, os_error)); |
925 } | 974 } |
926 core_->read_iobuffer_ = NULL; | 975 core_->read_iobuffer_ = NULL; |
976 core_->read_buffer_length_ = 0; | |
927 DoReadCallback(rv); | 977 DoReadCallback(rv); |
928 } | 978 } |
929 | 979 |
930 void TCPClientSocketWin::DidCompleteWrite() { | 980 void TCPClientSocketWin::DidCompleteWrite() { |
931 DCHECK(waiting_write_); | 981 DCHECK(waiting_write_); |
932 | 982 |
933 DWORD num_bytes, flags; | 983 DWORD num_bytes, flags; |
934 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 984 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
935 &num_bytes, FALSE, &flags); | 985 &num_bytes, FALSE, &flags); |
936 WSAResetEvent(core_->write_overlapped_.hEvent); | 986 WSAResetEvent(core_->write_overlapped_.hEvent); |
(...skipping 19 matching lines...) Expand all Loading... | |
956 if (num_bytes > 0) | 1006 if (num_bytes > 0) |
957 use_history_.set_was_used_to_convey_data(); | 1007 use_history_.set_was_used_to_convey_data(); |
958 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, | 1008 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, |
959 core_->write_iobuffer_->data()); | 1009 core_->write_iobuffer_->data()); |
960 } | 1010 } |
961 } | 1011 } |
962 core_->write_iobuffer_ = NULL; | 1012 core_->write_iobuffer_ = NULL; |
963 DoWriteCallback(rv); | 1013 DoWriteCallback(rv); |
964 } | 1014 } |
965 | 1015 |
1016 void TCPClientSocketWin::DidSignalRead() { | |
1017 DCHECK(waiting_read_); | |
1018 int os_error = 0; | |
1019 WSANETWORKEVENTS network_events; | |
1020 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | |
1021 &network_events); | |
1022 if (rv == SOCKET_ERROR) { | |
1023 os_error = WSAGetLastError(); | |
1024 rv = MapSystemError(os_error); | |
1025 } else { | |
1026 if (network_events.lNetworkEvents & FD_READ) { | |
1027 rv = recv(socket_, core_->read_iobuffer_->data(), | |
rvargas (doing something else)
2012/10/23 00:19:40
The bulk of this condition is basically the same c
pmeenan
2012/10/23 14:29:54
Done.
| |
1028 core_->read_buffer_length_, 0); | |
1029 if (rv == SOCKET_ERROR) { | |
1030 os_error = WSAGetLastError(); | |
1031 if (os_error == WSAEWOULDBLOCK) { | |
1032 core_->WatchForRead(); | |
1033 return; | |
1034 } else { | |
1035 rv = MapSystemError(os_error); | |
1036 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | |
1037 CreateNetLogSocketErrorCallback(rv, os_error)); | |
1038 } | |
1039 } else { | |
1040 base::StatsCounter read_bytes("tcp.read_bytes"); | |
1041 if (rv > 0) { | |
1042 use_history_.set_was_used_to_convey_data(); | |
1043 read_bytes.Add(rv); | |
1044 num_bytes_read_ += rv; | |
1045 } | |
1046 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, | |
1047 core_->read_iobuffer_->data()); | |
1048 } | |
1049 } else if (network_events.lNetworkEvents & FD_CLOSE) { | |
1050 if (network_events.iErrorCode[FD_CLOSE_BIT]) { | |
1051 rv = MapSystemError(network_events.iErrorCode[FD_CLOSE_BIT]); | |
1052 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | |
1053 CreateNetLogSocketErrorCallback(rv, os_error)); | |
1054 } else { | |
1055 rv = 0; | |
1056 } | |
1057 } else { | |
1058 // This should not happen but I have seen cases where we will get | |
1059 // signaled but the network events flags are all clear (0). | |
1060 core_->WatchForRead(); | |
1061 return; | |
1062 } | |
1063 } | |
1064 waiting_read_ = false; | |
1065 core_->read_iobuffer_ = NULL; | |
1066 core_->read_buffer_length_ = 0; | |
1067 DoReadCallback(rv); | |
1068 } | |
1069 | |
966 } // namespace net | 1070 } // namespace net |
OLD | NEW |