OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_socket.h" | 5 #include "net/socket/tcp_socket.h" |
6 #include "net/socket/tcp_socket_win.h" | 6 #include "net/socket/tcp_socket_win.h" |
7 | 7 |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <mstcpip.h> | 9 #include <mstcpip.h> |
10 | 10 |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
482 if (os_error != WSAEWOULDBLOCK) | 482 if (os_error != WSAEWOULDBLOCK) |
483 return false; | 483 return false; |
484 | 484 |
485 return true; | 485 return true; |
486 } | 486 } |
487 | 487 |
488 int TCPSocketWin::Read(IOBuffer* buf, | 488 int TCPSocketWin::Read(IOBuffer* buf, |
489 int buf_len, | 489 int buf_len, |
490 const CompletionCallback& callback) { | 490 const CompletionCallback& callback) { |
491 DCHECK(CalledOnValidThread()); | 491 DCHECK(CalledOnValidThread()); |
492 DCHECK_NE(socket_, INVALID_SOCKET); | |
493 DCHECK(!waiting_read_); | |
494 CHECK(read_callback_.is_null()); | |
495 DCHECK(!core_->read_iobuffer_.get()); | 492 DCHECK(!core_->read_iobuffer_.get()); |
xunjieli
2017/03/06 14:43:31
Note: This is not moved to ReadIfReady() because w
| |
496 | 493 // base::Unretained() is safe because RetryRead() won't be called when |this| |
497 return DoRead(buf, buf_len, callback); | 494 // is gone. |
495 int rv = | |
496 ReadIfReady(buf, buf_len, | |
497 base::Bind(&TCPSocketWin::RetryRead, base::Unretained(this))); | |
498 if (rv != ERR_IO_PENDING) | |
499 return rv; | |
500 read_callback_ = callback; | |
501 core_->read_iobuffer_ = buf; | |
502 core_->read_buffer_length_ = buf_len; | |
503 return ERR_IO_PENDING; | |
498 } | 504 } |
499 | 505 |
500 int TCPSocketWin::ReadIfReady(IOBuffer* buf, | 506 int TCPSocketWin::ReadIfReady(IOBuffer* buf, |
501 int buf_len, | 507 int buf_len, |
502 const CompletionCallback& callback) { | 508 const CompletionCallback& callback) { |
503 DCHECK(CalledOnValidThread()); | 509 DCHECK(CalledOnValidThread()); |
504 // TODO(xunjieli): Implement this. | 510 DCHECK_NE(socket_, INVALID_SOCKET); |
505 return ERR_READ_IF_READY_NOT_IMPLEMENTED; | 511 DCHECK(!waiting_read_); |
512 DCHECK(read_if_ready_callback_.is_null()); | |
513 | |
514 if (!core_->non_blocking_reads_initialized_) { | |
515 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_READ | FD_CLOSE); | |
516 core_->non_blocking_reads_initialized_ = true; | |
517 } | |
518 int rv = recv(socket_, buf->data(), buf_len, 0); | |
519 int os_error = WSAGetLastError(); | |
520 if (rv == SOCKET_ERROR) { | |
521 if (os_error != WSAEWOULDBLOCK) { | |
522 int net_error = MapSystemError(os_error); | |
523 net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR, | |
524 CreateNetLogSocketErrorCallback(net_error, os_error)); | |
525 return net_error; | |
526 } | |
527 } else { | |
528 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_RECEIVED, rv, | |
529 buf->data()); | |
530 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | |
531 return rv; | |
532 } | |
533 | |
534 waiting_read_ = true; | |
535 read_if_ready_callback_ = callback; | |
536 core_->WatchForRead(); | |
537 return ERR_IO_PENDING; | |
506 } | 538 } |
507 | 539 |
508 int TCPSocketWin::Write(IOBuffer* buf, | 540 int TCPSocketWin::Write(IOBuffer* buf, |
509 int buf_len, | 541 int buf_len, |
510 const CompletionCallback& callback) { | 542 const CompletionCallback& callback) { |
511 DCHECK(CalledOnValidThread()); | 543 DCHECK(CalledOnValidThread()); |
512 DCHECK_NE(socket_, INVALID_SOCKET); | 544 DCHECK_NE(socket_, INVALID_SOCKET); |
513 DCHECK(!waiting_write_); | 545 DCHECK(!waiting_write_); |
514 CHECK(write_callback_.is_null()); | 546 CHECK(write_callback_.is_null()); |
515 DCHECK_GT(buf_len, 0); | 547 DCHECK_GT(buf_len, 0); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
678 } | 710 } |
679 core_->Detach(); | 711 core_->Detach(); |
680 core_ = NULL; | 712 core_ = NULL; |
681 } | 713 } |
682 | 714 |
683 waiting_connect_ = false; | 715 waiting_connect_ = false; |
684 waiting_read_ = false; | 716 waiting_read_ = false; |
685 waiting_write_ = false; | 717 waiting_write_ = false; |
686 | 718 |
687 read_callback_.Reset(); | 719 read_callback_.Reset(); |
720 read_if_ready_callback_.Reset(); | |
688 write_callback_.Reset(); | 721 write_callback_.Reset(); |
689 peer_address_.reset(); | 722 peer_address_.reset(); |
690 connect_os_error_ = 0; | 723 connect_os_error_ = 0; |
691 } | 724 } |
692 | 725 |
693 void TCPSocketWin::DetachFromThread() { | 726 void TCPSocketWin::DetachFromThread() { |
694 base::NonThreadSafe::DetachFromThread(); | 727 base::NonThreadSafe::DetachFromThread(); |
695 } | 728 } |
696 | 729 |
697 void TCPSocketWin::StartLoggingMultipleConnectAttempts( | 730 void TCPSocketWin::StartLoggingMultipleConnectAttempts( |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
872 return; | 905 return; |
873 } | 906 } |
874 | 907 |
875 net_log_.EndEvent( | 908 net_log_.EndEvent( |
876 NetLogEventType::TCP_CONNECT, | 909 NetLogEventType::TCP_CONNECT, |
877 CreateNetLogSourceAddressCallback( | 910 CreateNetLogSourceAddressCallback( |
878 reinterpret_cast<const struct sockaddr*>(&source_address), | 911 reinterpret_cast<const struct sockaddr*>(&source_address), |
879 sizeof(source_address))); | 912 sizeof(source_address))); |
880 } | 913 } |
881 | 914 |
882 int TCPSocketWin::DoRead(IOBuffer* buf, int buf_len, | 915 void TCPSocketWin::RetryRead(int rv) { |
883 const CompletionCallback& callback) { | 916 DCHECK(core_->read_iobuffer_); |
884 if (!core_->non_blocking_reads_initialized_) { | 917 |
885 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, | 918 if (rv == OK) { |
886 FD_READ | FD_CLOSE); | 919 // base::Unretained() is safe because RetryRead() won't be called when |
887 core_->non_blocking_reads_initialized_ = true; | 920 // |this| is gone. |
921 rv = ReadIfReady( | |
922 core_->read_iobuffer_.get(), core_->read_buffer_length_, | |
923 base::Bind(&TCPSocketWin::RetryRead, base::Unretained(this))); | |
924 if (rv == ERR_IO_PENDING) | |
925 return; | |
888 } | 926 } |
889 int rv = recv(socket_, buf->data(), buf_len, 0); | 927 core_->read_iobuffer_ = nullptr; |
890 int os_error = WSAGetLastError(); | 928 core_->read_buffer_length_ = 0; |
891 if (rv == SOCKET_ERROR) { | 929 base::ResetAndReturn(&read_callback_).Run(rv); |
892 if (os_error != WSAEWOULDBLOCK) { | |
893 int net_error = MapSystemError(os_error); | |
894 net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR, | |
895 CreateNetLogSocketErrorCallback(net_error, os_error)); | |
896 return net_error; | |
897 } | |
898 } else { | |
899 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_RECEIVED, rv, | |
900 buf->data()); | |
901 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | |
902 return rv; | |
903 } | |
904 | |
905 waiting_read_ = true; | |
906 read_callback_ = callback; | |
907 core_->read_iobuffer_ = buf; | |
908 core_->read_buffer_length_ = buf_len; | |
909 core_->WatchForRead(); | |
910 return ERR_IO_PENDING; | |
911 } | 930 } |
912 | 931 |
913 void TCPSocketWin::DidCompleteConnect() { | 932 void TCPSocketWin::DidCompleteConnect() { |
914 DCHECK(waiting_connect_); | 933 DCHECK(waiting_connect_); |
915 DCHECK(!read_callback_.is_null()); | 934 DCHECK(!read_callback_.is_null()); |
916 int result; | 935 int result; |
917 | 936 |
918 WSANETWORKEVENTS events; | 937 WSANETWORKEVENTS events; |
919 int rv; | 938 int rv; |
920 int os_error = 0; | 939 int os_error = 0; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
982 } | 1001 } |
983 | 1002 |
984 core_->write_iobuffer_ = NULL; | 1003 core_->write_iobuffer_ = NULL; |
985 | 1004 |
986 DCHECK_NE(rv, ERR_IO_PENDING); | 1005 DCHECK_NE(rv, ERR_IO_PENDING); |
987 base::ResetAndReturn(&write_callback_).Run(rv); | 1006 base::ResetAndReturn(&write_callback_).Run(rv); |
988 } | 1007 } |
989 | 1008 |
990 void TCPSocketWin::DidSignalRead() { | 1009 void TCPSocketWin::DidSignalRead() { |
991 DCHECK(waiting_read_); | 1010 DCHECK(waiting_read_); |
992 DCHECK(!read_callback_.is_null()); | 1011 DCHECK(!read_if_ready_callback_.is_null()); |
993 | 1012 |
994 int os_error = 0; | 1013 int os_error = 0; |
995 WSANETWORKEVENTS network_events; | 1014 WSANETWORKEVENTS network_events; |
996 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | 1015 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, |
997 &network_events); | 1016 &network_events); |
998 os_error = WSAGetLastError(); | 1017 os_error = WSAGetLastError(); |
999 | 1018 |
1000 if (rv == SOCKET_ERROR) { | 1019 if (rv == SOCKET_ERROR) { |
1001 rv = MapSystemError(os_error); | 1020 rv = MapSystemError(os_error); |
1002 } else if (network_events.lNetworkEvents) { | 1021 } else if (network_events.lNetworkEvents) { |
1003 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462778 is | 1022 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462778 is |
1004 // fixed. | 1023 // fixed. |
1005 tracked_objects::ScopedTracker tracking_profile2( | 1024 tracked_objects::ScopedTracker tracking_profile2( |
1006 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1025 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1007 "462778 TCPSocketWin::DidSignalRead -> DoRead")); | 1026 "462778 TCPSocketWin::DidSignalRead -> DoRead")); |
1008 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); | 1027 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); |
1009 // If network_events.lNetworkEvents is FD_CLOSE and | 1028 // If network_events.lNetworkEvents is FD_CLOSE and |
1010 // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful | 1029 // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful |
1011 // connection closure. It is tempting to directly set rv to 0 in | 1030 // connection closure. It is tempting to directly set rv to 0 in |
1012 // this case, but the MSDN pages for WSAEventSelect and | 1031 // this case, but the MSDN pages for WSAEventSelect and |
1013 // WSAAsyncSelect recommend we still call DoRead(): | 1032 // WSAAsyncSelect recommend we still call RetryRead(): |
1014 // FD_CLOSE should only be posted after all data is read from a | 1033 // FD_CLOSE should only be posted after all data is read from a |
1015 // socket, but an application should check for remaining data upon | 1034 // socket, but an application should check for remaining data upon |
1016 // receipt of FD_CLOSE to avoid any possibility of losing data. | 1035 // receipt of FD_CLOSE to avoid any possibility of losing data. |
1017 // | 1036 // |
1018 // If network_events.iErrorCode[FD_READ_BIT] or | 1037 // If network_events.iErrorCode[FD_READ_BIT] or |
1019 // network_events.iErrorCode[FD_CLOSE_BIT] is nonzero, still call | 1038 // network_events.iErrorCode[FD_CLOSE_BIT] is nonzero, still call |
1020 // DoRead() because recv() reports a more accurate error code | 1039 // RetryRead() because recv() reports a more accurate error code |
1021 // (WSAECONNRESET vs. WSAECONNABORTED) when the connection was | 1040 // (WSAECONNRESET vs. WSAECONNABORTED) when the connection was |
1022 // reset. | 1041 // reset. |
1023 rv = DoRead(core_->read_iobuffer_.get(), core_->read_buffer_length_, | 1042 waiting_read_ = false; |
1024 read_callback_); | 1043 base::ResetAndReturn(&read_if_ready_callback_).Run(OK); |
1025 if (rv == ERR_IO_PENDING) | 1044 return; |
davidben
2017/03/06 22:09:08
I think you can replace these three lines with rv
xunjieli
2017/03/06 22:14:03
Done. Neat!
| |
1026 return; | |
1027 } else { | 1045 } else { |
1028 // This may happen because Read() may succeed synchronously and | 1046 // This may happen because Read() may succeed synchronously and |
1029 // consume all the received data without resetting the event object. | 1047 // consume all the received data without resetting the event object. |
1030 core_->WatchForRead(); | 1048 core_->WatchForRead(); |
1031 return; | 1049 return; |
1032 } | 1050 } |
1033 | 1051 |
1052 DCHECK_NE(rv, ERR_IO_PENDING); | |
1034 waiting_read_ = false; | 1053 waiting_read_ = false; |
1035 core_->read_iobuffer_ = NULL; | 1054 base::ResetAndReturn(&read_if_ready_callback_).Run(rv); |
1036 core_->read_buffer_length_ = 0; | |
1037 | |
1038 DCHECK_NE(rv, ERR_IO_PENDING); | |
1039 base::ResetAndReturn(&read_callback_).Run(rv); | |
1040 } | 1055 } |
1041 | 1056 |
1042 bool TCPSocketWin::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const { | 1057 bool TCPSocketWin::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const { |
1043 DCHECK(out_rtt); | 1058 DCHECK(out_rtt); |
1044 // TODO(bmcquade): Consider implementing using | 1059 // TODO(bmcquade): Consider implementing using |
1045 // GetPerTcpConnectionEStats/GetPerTcp6ConnectionEStats. | 1060 // GetPerTcpConnectionEStats/GetPerTcp6ConnectionEStats. |
1046 return false; | 1061 return false; |
1047 } | 1062 } |
1048 | 1063 |
1049 } // namespace net | 1064 } // namespace net |
OLD | NEW |