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 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_) { |
slamm
2012/10/25 19:51:48
Change 313 to "else if".
pmeenan
2012/10/26 14:03:49
Done.
| |
315 core_->socket_->DidSignalRead(); | |
316 } else { | |
317 core_->socket_->DidCompleteRead(); | |
318 } | |
305 } | 319 } |
306 } | 320 } |
307 | 321 |
308 core_->Release(); | 322 core_->Release(); |
309 } | 323 } |
310 | 324 |
311 void TCPClientSocketWin::Core::WriteDelegate::OnObjectSignaled( | 325 void TCPClientSocketWin::Core::WriteDelegate::OnObjectSignaled( |
312 HANDLE object) { | 326 HANDLE object) { |
313 DCHECK_EQ(object, core_->write_overlapped_.hEvent); | 327 DCHECK_EQ(object, core_->write_overlapped_.hEvent); |
314 if (core_->socket_) | 328 if (core_->socket_) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 int rv = DoRead(buf, buf_len, callback); |
715 | 728 |
716 WSABUF read_buffer; | 729 return rv; |
slamm
2012/10/25 19:51:48
Drop rv?
return DoRead(buf, buf_len, callback);
pmeenan
2012/10/26 14:03:49
Done. Wasn't sure if convention allowed for retur
| |
717 read_buffer.len = buf_len; | |
718 read_buffer.buf = buf->data(); | |
719 | |
720 // TODO(wtc): Remove the assertion after enough testing. | |
721 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | |
722 DWORD num, flags = 0; | |
723 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags, | |
724 &core_->read_overlapped_, NULL); | |
725 if (rv == 0) { | |
726 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | |
727 base::StatsCounter read_bytes("tcp.read_bytes"); | |
728 read_bytes.Add(num); | |
729 num_bytes_read_ += num; | |
730 if (num > 0) | |
731 use_history_.set_was_used_to_convey_data(); | |
732 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, | |
733 buf->data()); | |
734 return static_cast<int>(num); | |
735 } | |
736 } else { | |
737 int os_error = WSAGetLastError(); | |
738 if (os_error != WSA_IO_PENDING) { | |
739 int net_error = MapSystemError(os_error); | |
740 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | |
741 CreateNetLogSocketErrorCallback(net_error, os_error)); | |
742 return net_error; | |
743 } | |
744 } | |
745 core_->WatchForRead(); | |
746 waiting_read_ = true; | |
747 read_callback_ = callback; | |
748 core_->read_iobuffer_ = buf; | |
749 return ERR_IO_PENDING; | |
750 } | 730 } |
751 | 731 |
752 int TCPClientSocketWin::Write(IOBuffer* buf, | 732 int TCPClientSocketWin::Write(IOBuffer* buf, |
753 int buf_len, | 733 int buf_len, |
754 const CompletionCallback& callback) { | 734 const CompletionCallback& callback) { |
755 DCHECK(CalledOnValidThread()); | 735 DCHECK(CalledOnValidThread()); |
756 DCHECK_NE(socket_, INVALID_SOCKET); | 736 DCHECK_NE(socket_, INVALID_SOCKET); |
757 DCHECK(!waiting_write_); | 737 DCHECK(!waiting_write_); |
758 DCHECK(write_callback_.is_null()); | 738 DCHECK(write_callback_.is_null()); |
759 DCHECK_GT(buf_len, 0); | 739 DCHECK_GT(buf_len, 0); |
760 DCHECK(!core_->write_iobuffer_); | 740 DCHECK(!core_->write_iobuffer_); |
761 | 741 |
762 base::StatsCounter writes("tcp.writes"); | 742 base::StatsCounter writes("tcp.writes"); |
763 writes.Increment(); | 743 writes.Increment(); |
764 | 744 |
765 WSABUF write_buffer; | 745 WSABUF write_buffer; |
766 write_buffer.len = buf_len; | 746 write_buffer.len = buf_len; |
767 write_buffer.buf = buf->data(); | 747 write_buffer.buf = buf->data(); |
768 core_->write_buffer_length_ = buf_len; | |
769 | 748 |
770 // TODO(wtc): Remove the assertion after enough testing. | 749 // TODO(wtc): Remove the assertion after enough testing. |
771 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 750 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
772 DWORD num; | 751 DWORD num; |
773 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, | 752 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, |
774 &core_->write_overlapped_, NULL); | 753 &core_->write_overlapped_, NULL); |
775 if (rv == 0) { | 754 if (rv == 0) { |
776 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 755 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
777 rv = static_cast<int>(num); | 756 rv = static_cast<int>(num); |
778 if (rv > buf_len || rv < 0) { | 757 if (rv > buf_len || rv < 0) { |
(...skipping 13 matching lines...) Expand all Loading... | |
792 } | 771 } |
793 } else { | 772 } else { |
794 int os_error = WSAGetLastError(); | 773 int os_error = WSAGetLastError(); |
795 if (os_error != WSA_IO_PENDING) { | 774 if (os_error != WSA_IO_PENDING) { |
796 int net_error = MapSystemError(os_error); | 775 int net_error = MapSystemError(os_error); |
797 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 776 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
798 CreateNetLogSocketErrorCallback(net_error, os_error)); | 777 CreateNetLogSocketErrorCallback(net_error, os_error)); |
799 return net_error; | 778 return net_error; |
800 } | 779 } |
801 } | 780 } |
802 core_->WatchForWrite(); | |
803 waiting_write_ = true; | 781 waiting_write_ = true; |
804 write_callback_ = callback; | 782 write_callback_ = callback; |
805 core_->write_iobuffer_ = buf; | 783 core_->write_iobuffer_ = buf; |
784 core_->write_buffer_length_ = buf_len; | |
785 core_->WatchForWrite(); | |
806 return ERR_IO_PENDING; | 786 return ERR_IO_PENDING; |
807 } | 787 } |
808 | 788 |
809 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { | 789 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { |
810 DCHECK(CalledOnValidThread()); | 790 DCHECK(CalledOnValidThread()); |
811 return SetSocketReceiveBufferSize(socket_, size); | 791 return SetSocketReceiveBufferSize(socket_, size); |
812 } | 792 } |
813 | 793 |
814 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { | 794 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { |
815 DCHECK(CalledOnValidThread()); | 795 DCHECK(CalledOnValidThread()); |
816 return SetSocketSendBufferSize(socket_, size); | 796 return SetSocketSendBufferSize(socket_, size); |
817 } | 797 } |
818 | 798 |
819 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) { | 799 bool TCPClientSocketWin::SetKeepAlive(bool enable, int delay) { |
820 return SetTCPKeepAlive(socket_, enable, delay); | 800 return SetTCPKeepAlive(socket_, enable, delay); |
821 } | 801 } |
822 | 802 |
823 bool TCPClientSocketWin::SetNoDelay(bool no_delay) { | 803 bool TCPClientSocketWin::SetNoDelay(bool no_delay) { |
824 return DisableNagle(socket_, no_delay); | 804 return DisableNagle(socket_, no_delay); |
825 } | 805 } |
826 | 806 |
807 void TCPClientSocketWin::DisableOverlappedReads() { | |
808 g_disable_overlapped_reads = true; | |
809 } | |
810 | |
827 void TCPClientSocketWin::LogConnectCompletion(int net_error) { | 811 void TCPClientSocketWin::LogConnectCompletion(int net_error) { |
828 if (net_error == OK) | 812 if (net_error == OK) |
829 UpdateConnectionTypeHistograms(CONNECTION_ANY); | 813 UpdateConnectionTypeHistograms(CONNECTION_ANY); |
830 | 814 |
831 if (net_error != OK) { | 815 if (net_error != OK) { |
832 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); | 816 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); |
833 return; | 817 return; |
834 } | 818 } |
835 | 819 |
836 struct sockaddr_storage source_address; | 820 struct sockaddr_storage source_address; |
837 socklen_t addrlen = sizeof(source_address); | 821 socklen_t addrlen = sizeof(source_address); |
838 int rv = getsockname( | 822 int rv = getsockname( |
839 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); | 823 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); |
840 if (rv != 0) { | 824 if (rv != 0) { |
841 LOG(ERROR) << "getsockname() [rv: " << rv | 825 LOG(ERROR) << "getsockname() [rv: " << rv |
842 << "] error: " << WSAGetLastError(); | 826 << "] error: " << WSAGetLastError(); |
843 NOTREACHED(); | 827 NOTREACHED(); |
844 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); | 828 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); |
845 return; | 829 return; |
846 } | 830 } |
847 | 831 |
848 net_log_.EndEvent( | 832 net_log_.EndEvent( |
849 NetLog::TYPE_TCP_CONNECT, | 833 NetLog::TYPE_TCP_CONNECT, |
850 CreateNetLogSourceAddressCallback( | 834 CreateNetLogSourceAddressCallback( |
851 reinterpret_cast<const struct sockaddr*>(&source_address), | 835 reinterpret_cast<const struct sockaddr*>(&source_address), |
852 sizeof(source_address))); | 836 sizeof(source_address))); |
853 } | 837 } |
854 | 838 |
839 int TCPClientSocketWin::DoRead(IOBuffer* buf, int buf_len, | |
840 const CompletionCallback& callback) { | |
841 if (core_->disable_overlapped_reads_) { | |
842 if (!core_->non_blocking_reads_initialized_) { | |
843 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, | |
844 FD_READ | FD_CLOSE); | |
845 core_->non_blocking_reads_initialized_ = true; | |
846 } | |
847 int rv = recv(socket_, buf->data(), buf_len, 0); | |
848 if (rv == SOCKET_ERROR) { | |
849 int os_error = WSAGetLastError(); | |
850 if (os_error != WSAEWOULDBLOCK) { | |
851 int net_error = MapSystemError(os_error); | |
852 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | |
853 CreateNetLogSocketErrorCallback(net_error, os_error)); | |
854 return net_error; | |
855 } | |
856 } else { | |
857 base::StatsCounter read_bytes("tcp.read_bytes"); | |
858 if (rv > 0) { | |
859 use_history_.set_was_used_to_convey_data(); | |
860 read_bytes.Add(rv); | |
861 num_bytes_read_ += rv; | |
862 } | |
863 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, | |
864 buf->data()); | |
865 return rv; | |
866 } | |
867 } else { | |
868 buf_len = core_->ThrottleReadSize(buf_len); | |
869 | |
870 WSABUF read_buffer; | |
871 read_buffer.len = buf_len; | |
872 read_buffer.buf = buf->data(); | |
873 | |
874 // TODO(wtc): Remove the assertion after enough testing. | |
875 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | |
876 DWORD num; | |
877 DWORD flags = 0; | |
878 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags, | |
879 &core_->read_overlapped_, NULL); | |
880 if (rv == 0) { | |
881 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | |
882 base::StatsCounter read_bytes("tcp.read_bytes"); | |
883 if (num > 0) { | |
884 use_history_.set_was_used_to_convey_data(); | |
885 read_bytes.Add(num); | |
886 num_bytes_read_ += num; | |
887 } | |
888 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, | |
889 buf->data()); | |
890 return static_cast<int>(num); | |
891 } | |
892 } else { | |
893 int os_error = WSAGetLastError(); | |
894 if (os_error != WSA_IO_PENDING) { | |
895 int net_error = MapSystemError(os_error); | |
896 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | |
897 CreateNetLogSocketErrorCallback(net_error, os_error)); | |
slamm
2012/10/25 19:51:48
Indent one more space.
pmeenan
2012/10/26 14:03:49
Had to switch to a 4-space intent instead, one mor
| |
898 return net_error; | |
899 } | |
900 } | |
901 } | |
902 | |
903 waiting_read_ = true; | |
904 read_callback_ = callback; | |
905 core_->read_iobuffer_ = buf; | |
906 core_->read_buffer_length_ = buf_len; | |
907 core_->WatchForRead(); | |
908 return ERR_IO_PENDING; | |
909 } | |
910 | |
855 void TCPClientSocketWin::DoReadCallback(int rv) { | 911 void TCPClientSocketWin::DoReadCallback(int rv) { |
856 DCHECK_NE(rv, ERR_IO_PENDING); | 912 DCHECK_NE(rv, ERR_IO_PENDING); |
857 DCHECK(!read_callback_.is_null()); | 913 DCHECK(!read_callback_.is_null()); |
858 | 914 |
859 // Since Run may result in Read being called, clear read_callback_ up front. | 915 // Since Run may result in Read being called, clear read_callback_ up front. |
860 CompletionCallback c = read_callback_; | 916 CompletionCallback c = read_callback_; |
861 read_callback_.Reset(); | 917 read_callback_.Reset(); |
862 c.Run(rv); | 918 c.Run(rv); |
863 } | 919 } |
864 | 920 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
917 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 973 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
918 num_bytes, core_->read_iobuffer_->data()); | 974 num_bytes, core_->read_iobuffer_->data()); |
919 rv = static_cast<int>(num_bytes); | 975 rv = static_cast<int>(num_bytes); |
920 } else { | 976 } else { |
921 int os_error = WSAGetLastError(); | 977 int os_error = WSAGetLastError(); |
922 rv = MapSystemError(os_error); | 978 rv = MapSystemError(os_error); |
923 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 979 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
924 CreateNetLogSocketErrorCallback(rv, os_error)); | 980 CreateNetLogSocketErrorCallback(rv, os_error)); |
925 } | 981 } |
926 core_->read_iobuffer_ = NULL; | 982 core_->read_iobuffer_ = NULL; |
983 core_->read_buffer_length_ = 0; | |
927 DoReadCallback(rv); | 984 DoReadCallback(rv); |
928 } | 985 } |
929 | 986 |
930 void TCPClientSocketWin::DidCompleteWrite() { | 987 void TCPClientSocketWin::DidCompleteWrite() { |
931 DCHECK(waiting_write_); | 988 DCHECK(waiting_write_); |
932 | 989 |
933 DWORD num_bytes, flags; | 990 DWORD num_bytes, flags; |
934 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 991 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
935 &num_bytes, FALSE, &flags); | 992 &num_bytes, FALSE, &flags); |
936 WSAResetEvent(core_->write_overlapped_.hEvent); | 993 WSAResetEvent(core_->write_overlapped_.hEvent); |
(...skipping 19 matching lines...) Expand all Loading... | |
956 if (num_bytes > 0) | 1013 if (num_bytes > 0) |
957 use_history_.set_was_used_to_convey_data(); | 1014 use_history_.set_was_used_to_convey_data(); |
958 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, | 1015 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, |
959 core_->write_iobuffer_->data()); | 1016 core_->write_iobuffer_->data()); |
960 } | 1017 } |
961 } | 1018 } |
962 core_->write_iobuffer_ = NULL; | 1019 core_->write_iobuffer_ = NULL; |
963 DoWriteCallback(rv); | 1020 DoWriteCallback(rv); |
964 } | 1021 } |
965 | 1022 |
1023 void TCPClientSocketWin::DidSignalRead() { | |
1024 DCHECK(waiting_read_); | |
1025 int os_error = 0; | |
1026 WSANETWORKEVENTS network_events; | |
1027 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | |
1028 &network_events); | |
1029 if (rv == SOCKET_ERROR) { | |
1030 os_error = WSAGetLastError(); | |
1031 rv = MapSystemError(os_error); | |
1032 } else { | |
1033 if (network_events.lNetworkEvents & FD_READ) { | |
slamm
2012/10/25 19:51:48
Change 1032 to "else if".
pmeenan
2012/10/26 14:03:49
Done.
| |
1034 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_, | |
1035 read_callback_); | |
1036 if (rv == ERR_IO_PENDING) | |
1037 return; | |
1038 } else if (network_events.lNetworkEvents & FD_CLOSE) { | |
1039 if (network_events.iErrorCode[FD_CLOSE_BIT]) { | |
1040 rv = MapSystemError(network_events.iErrorCode[FD_CLOSE_BIT]); | |
1041 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | |
1042 CreateNetLogSocketErrorCallback(rv, os_error)); | |
1043 } else { | |
1044 rv = 0; | |
1045 } | |
1046 } else { | |
1047 // This should not happen but I have seen cases where we will get | |
1048 // signaled but the network events flags are all clear (0). | |
1049 core_->WatchForRead(); | |
1050 return; | |
1051 } | |
1052 } | |
1053 waiting_read_ = false; | |
1054 core_->read_iobuffer_ = NULL; | |
1055 core_->read_buffer_length_ = 0; | |
1056 DoReadCallback(rv); | |
1057 } | |
1058 | |
966 } // namespace net | 1059 } // namespace net |
OLD | NEW |