Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: net/socket/tcp_socket_win.cc

Issue 2690943004: Add ReadIfReady() for tcp_socket_win (Closed)
Patch Set: self Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/socket/tcp_socket_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/socket/tcp_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698