OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 | 310 |
311 TCPClientSocketWin::TCPClientSocketWin(const AddressList& addresses, | 311 TCPClientSocketWin::TCPClientSocketWin(const AddressList& addresses, |
312 net::NetLog* net_log, | 312 net::NetLog* net_log, |
313 const net::NetLog::Source& source) | 313 const net::NetLog::Source& source) |
314 : socket_(INVALID_SOCKET), | 314 : socket_(INVALID_SOCKET), |
315 bound_socket_(INVALID_SOCKET), | 315 bound_socket_(INVALID_SOCKET), |
316 addresses_(addresses), | 316 addresses_(addresses), |
317 current_ai_(NULL), | 317 current_ai_(NULL), |
318 waiting_read_(false), | 318 waiting_read_(false), |
319 waiting_write_(false), | 319 waiting_write_(false), |
320 old_read_callback_(NULL), | |
321 write_callback_(NULL), | |
322 next_connect_state_(CONNECT_STATE_NONE), | 320 next_connect_state_(CONNECT_STATE_NONE), |
323 connect_os_error_(0), | 321 connect_os_error_(0), |
324 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 322 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
325 previously_disconnected_(false), | 323 previously_disconnected_(false), |
326 num_bytes_read_(0) { | 324 num_bytes_read_(0) { |
327 scoped_refptr<NetLog::EventParameters> params; | 325 scoped_refptr<NetLog::EventParameters> params; |
328 if (source.is_valid()) | 326 if (source.is_valid()) |
329 params = new NetLogSourceParameter("source_dependency", source); | 327 params = new NetLogSourceParameter("source_dependency", source); |
330 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 328 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
331 EnsureWinsockInit(); | 329 EnsureWinsockInit(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 bound_socket_ = INVALID_SOCKET; | 373 bound_socket_ = INVALID_SOCKET; |
376 return MapSystemError(error); | 374 return MapSystemError(error); |
377 } | 375 } |
378 | 376 |
379 bind_address_.reset(new IPEndPoint(address)); | 377 bind_address_.reset(new IPEndPoint(address)); |
380 | 378 |
381 return 0; | 379 return 0; |
382 } | 380 } |
383 | 381 |
384 | 382 |
385 int TCPClientSocketWin::Connect(OldCompletionCallback* callback) { | |
386 DCHECK(CalledOnValidThread()); | |
387 | |
388 // If already connected, then just return OK. | |
389 if (socket_ != INVALID_SOCKET) | |
390 return OK; | |
391 | |
392 base::StatsCounter connects("tcp.connect"); | |
393 connects.Increment(); | |
394 | |
395 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, | |
396 new AddressListNetLogParam(addresses_)); | |
397 | |
398 // We will try to connect to each address in addresses_. Start with the | |
399 // first one in the list. | |
400 next_connect_state_ = CONNECT_STATE_CONNECT; | |
401 current_ai_ = addresses_.head(); | |
402 | |
403 int rv = DoConnectLoop(OK); | |
404 if (rv == ERR_IO_PENDING) { | |
405 // Synchronous operation not supported. | |
406 DCHECK(callback); | |
407 old_read_callback_ = callback; | |
408 } else { | |
409 LogConnectCompletion(rv); | |
410 } | |
411 | |
412 return rv; | |
413 } | |
414 int TCPClientSocketWin::Connect(const CompletionCallback& callback) { | 383 int TCPClientSocketWin::Connect(const CompletionCallback& callback) { |
415 DCHECK(CalledOnValidThread()); | 384 DCHECK(CalledOnValidThread()); |
416 | 385 |
417 // If already connected, then just return OK. | 386 // If already connected, then just return OK. |
418 if (socket_ != INVALID_SOCKET) | 387 if (socket_ != INVALID_SOCKET) |
419 return OK; | 388 return OK; |
420 | 389 |
421 base::StatsCounter connects("tcp.connect"); | 390 base::StatsCounter connects("tcp.connect"); |
422 connects.Increment(); | 391 connects.Increment(); |
423 | 392 |
424 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, | 393 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, |
425 new AddressListNetLogParam(addresses_)); | 394 new AddressListNetLogParam(addresses_)); |
426 | 395 |
427 // We will try to connect to each address in addresses_. Start with the | 396 // We will try to connect to each address in addresses_. Start with the |
428 // first one in the list. | 397 // first one in the list. |
429 next_connect_state_ = CONNECT_STATE_CONNECT; | 398 next_connect_state_ = CONNECT_STATE_CONNECT; |
430 current_ai_ = addresses_.head(); | 399 current_ai_ = addresses_.head(); |
431 | 400 |
432 int rv = DoConnectLoop(OK); | 401 int rv = DoConnectLoop(OK); |
433 if (rv == ERR_IO_PENDING) { | 402 if (rv == ERR_IO_PENDING) { |
434 // Synchronous operation not supported. | 403 // Synchronous operation not supported. |
435 DCHECK(!callback.is_null()); | 404 DCHECK(!callback.is_null()); |
| 405 // TODO(ajwong): Is setting read_callback_ the right thing to do here?? |
436 read_callback_ = callback; | 406 read_callback_ = callback; |
437 } else { | 407 } else { |
438 LogConnectCompletion(rv); | 408 LogConnectCompletion(rv); |
439 } | 409 } |
440 | 410 |
441 return rv; | 411 return rv; |
442 } | 412 } |
443 | 413 |
444 int TCPClientSocketWin::DoConnectLoop(int result) { | 414 int TCPClientSocketWin::DoConnectLoop(int result) { |
445 DCHECK_NE(next_connect_state_, CONNECT_STATE_NONE); | 415 DCHECK_NE(next_connect_state_, CONNECT_STATE_NONE); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 int64 TCPClientSocketWin::NumBytesRead() const { | 668 int64 TCPClientSocketWin::NumBytesRead() const { |
699 return num_bytes_read_; | 669 return num_bytes_read_; |
700 } | 670 } |
701 | 671 |
702 base::TimeDelta TCPClientSocketWin::GetConnectTimeMicros() const { | 672 base::TimeDelta TCPClientSocketWin::GetConnectTimeMicros() const { |
703 return connect_time_micros_; | 673 return connect_time_micros_; |
704 } | 674 } |
705 | 675 |
706 int TCPClientSocketWin::Read(IOBuffer* buf, | 676 int TCPClientSocketWin::Read(IOBuffer* buf, |
707 int buf_len, | 677 int buf_len, |
708 OldCompletionCallback* callback) { | |
709 DCHECK(CalledOnValidThread()); | |
710 DCHECK_NE(socket_, INVALID_SOCKET); | |
711 DCHECK(!waiting_read_); | |
712 DCHECK(!old_read_callback_ && read_callback_.is_null()); | |
713 DCHECK(!core_->read_iobuffer_); | |
714 | |
715 buf_len = core_->ThrottleReadSize(buf_len); | |
716 | |
717 core_->read_buffer_.len = buf_len; | |
718 core_->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_, &core_->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 core_->read_buffer_.buf); | |
734 return static_cast<int>(num); | |
735 } | |
736 } else { | |
737 int os_error = WSAGetLastError(); | |
738 if (os_error != WSA_IO_PENDING) | |
739 return MapSystemError(os_error); | |
740 } | |
741 core_->WatchForRead(); | |
742 waiting_read_ = true; | |
743 old_read_callback_ = callback; | |
744 core_->read_iobuffer_ = buf; | |
745 return ERR_IO_PENDING; | |
746 } | |
747 int TCPClientSocketWin::Read(IOBuffer* buf, | |
748 int buf_len, | |
749 const CompletionCallback& callback) { | 678 const CompletionCallback& callback) { |
750 DCHECK(CalledOnValidThread()); | 679 DCHECK(CalledOnValidThread()); |
751 DCHECK_NE(socket_, INVALID_SOCKET); | 680 DCHECK_NE(socket_, INVALID_SOCKET); |
752 DCHECK(!waiting_read_); | 681 DCHECK(!waiting_read_); |
753 DCHECK(!old_read_callback_ && read_callback_.is_null()); | 682 DCHECK(read_callback_.is_null()); |
754 DCHECK(!core_->read_iobuffer_); | 683 DCHECK(!core_->read_iobuffer_); |
755 | 684 |
756 buf_len = core_->ThrottleReadSize(buf_len); | 685 buf_len = core_->ThrottleReadSize(buf_len); |
757 | 686 |
758 core_->read_buffer_.len = buf_len; | 687 core_->read_buffer_.len = buf_len; |
759 core_->read_buffer_.buf = buf->data(); | 688 core_->read_buffer_.buf = buf->data(); |
760 | 689 |
761 // TODO(wtc): Remove the assertion after enough testing. | 690 // TODO(wtc): Remove the assertion after enough testing. |
762 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | 691 AssertEventNotSignaled(core_->read_overlapped_.hEvent); |
763 DWORD num, flags = 0; | 692 DWORD num, flags = 0; |
(...skipping 17 matching lines...) Expand all Loading... |
781 } | 710 } |
782 core_->WatchForRead(); | 711 core_->WatchForRead(); |
783 waiting_read_ = true; | 712 waiting_read_ = true; |
784 read_callback_ = callback; | 713 read_callback_ = callback; |
785 core_->read_iobuffer_ = buf; | 714 core_->read_iobuffer_ = buf; |
786 return ERR_IO_PENDING; | 715 return ERR_IO_PENDING; |
787 } | 716 } |
788 | 717 |
789 int TCPClientSocketWin::Write(IOBuffer* buf, | 718 int TCPClientSocketWin::Write(IOBuffer* buf, |
790 int buf_len, | 719 int buf_len, |
791 OldCompletionCallback* callback) { | 720 const CompletionCallback& callback) { |
792 DCHECK(CalledOnValidThread()); | 721 DCHECK(CalledOnValidThread()); |
793 DCHECK_NE(socket_, INVALID_SOCKET); | 722 DCHECK_NE(socket_, INVALID_SOCKET); |
794 DCHECK(!waiting_write_); | 723 DCHECK(!waiting_write_); |
795 DCHECK(!write_callback_); | 724 DCHECK(write_callback_.is_null()); |
796 DCHECK_GT(buf_len, 0); | 725 DCHECK_GT(buf_len, 0); |
797 DCHECK(!core_->write_iobuffer_); | 726 DCHECK(!core_->write_iobuffer_); |
798 | 727 |
799 base::StatsCounter writes("tcp.writes"); | 728 base::StatsCounter writes("tcp.writes"); |
800 writes.Increment(); | 729 writes.Increment(); |
801 | 730 |
802 core_->write_buffer_.len = buf_len; | 731 core_->write_buffer_.len = buf_len; |
803 core_->write_buffer_.buf = buf->data(); | 732 core_->write_buffer_.buf = buf->data(); |
804 core_->write_buffer_length_ = buf_len; | 733 core_->write_buffer_length_ = buf_len; |
805 | 734 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 reinterpret_cast<const struct sockaddr*>(&source_address), | 803 reinterpret_cast<const struct sockaddr*>(&source_address), |
875 sizeof(source_address)); | 804 sizeof(source_address)); |
876 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 805 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, |
877 make_scoped_refptr(new NetLogStringParameter( | 806 make_scoped_refptr(new NetLogStringParameter( |
878 "source_address", | 807 "source_address", |
879 source_address_str))); | 808 source_address_str))); |
880 } | 809 } |
881 | 810 |
882 void TCPClientSocketWin::DoReadCallback(int rv) { | 811 void TCPClientSocketWin::DoReadCallback(int rv) { |
883 DCHECK_NE(rv, ERR_IO_PENDING); | 812 DCHECK_NE(rv, ERR_IO_PENDING); |
884 DCHECK(old_read_callback_ || !read_callback_.is_null()); | 813 DCHECK(!read_callback_.is_null()); |
885 | 814 |
886 // since Run may result in Read being called, clear read_callback_ up front. | 815 // Since Run may result in Read being called, clear read_callback_ up front. |
887 if (old_read_callback_) { | 816 CompletionCallback c = read_callback_; |
888 OldCompletionCallback* c = old_read_callback_; | 817 read_callback_.Reset(); |
889 old_read_callback_ = NULL; | 818 c.Run(rv); |
890 c->Run(rv); | |
891 } else { | |
892 CompletionCallback c = read_callback_; | |
893 read_callback_.Reset(); | |
894 c.Run(rv); | |
895 } | |
896 } | 819 } |
897 | 820 |
898 void TCPClientSocketWin::DoWriteCallback(int rv) { | 821 void TCPClientSocketWin::DoWriteCallback(int rv) { |
899 DCHECK_NE(rv, ERR_IO_PENDING); | 822 DCHECK_NE(rv, ERR_IO_PENDING); |
900 DCHECK(write_callback_); | 823 DCHECK(!write_callback_.is_null()); |
901 | 824 |
902 // since Run may result in Write being called, clear write_callback_ up front. | 825 // since Run may result in Write being called, clear write_callback_ up front. |
903 OldCompletionCallback* c = write_callback_; | 826 CompletionCallback c = write_callback_; |
904 write_callback_ = NULL; | 827 write_callback_.Reset(); |
905 c->Run(rv); | 828 c.Run(rv); |
906 } | 829 } |
907 | 830 |
908 void TCPClientSocketWin::DidCompleteConnect() { | 831 void TCPClientSocketWin::DidCompleteConnect() { |
909 DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE); | 832 DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE); |
910 int result; | 833 int result; |
911 | 834 |
912 WSANETWORKEVENTS events; | 835 WSANETWORKEVENTS events; |
913 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | 836 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, |
914 &events); | 837 &events); |
915 int os_error = 0; | 838 int os_error = 0; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 use_history_.set_was_used_to_convey_data(); | 903 use_history_.set_was_used_to_convey_data(); |
981 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, | 904 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, |
982 core_->write_buffer_.buf); | 905 core_->write_buffer_.buf); |
983 } | 906 } |
984 } | 907 } |
985 core_->write_iobuffer_ = NULL; | 908 core_->write_iobuffer_ = NULL; |
986 DoWriteCallback(rv); | 909 DoWriteCallback(rv); |
987 } | 910 } |
988 | 911 |
989 } // namespace net | 912 } // namespace net |
OLD | NEW |