Chromium Code Reviews| 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 |