Index: net/socket/socket_test_util.cc |
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc |
index 93fcf3d7bd053489980ab129072216a3893c9d96..ae393f13b6f4706550f42b2b056f113c023452eb 100644 |
--- a/net/socket/socket_test_util.cc |
+++ b/net/socket/socket_test_util.cc |
@@ -143,6 +143,17 @@ MockConnect::MockConnect(IoMode io_mode, int r, IPEndPoint addr) : |
MockConnect::~MockConnect() {} |
+bool SocketDataProvider::IsIdle() const { |
+ return true; |
+} |
+ |
+SocketDataProvider::SocketDataProvider() : socket_(nullptr) {} |
+ |
+SocketDataProvider::~SocketDataProvider() { |
+ if (socket_) |
+ socket_->OnDataProviderDestroyed(); |
+} |
+ |
StaticSocketDataHelper::StaticSocketDataHelper(MockRead* reads, |
size_t reads_count, |
MockWrite* writes, |
@@ -288,6 +299,7 @@ SequencedSocketData::SequencedSocketData(MockRead* reads, |
sequence_number_(0), |
read_state_(IDLE), |
write_state_(IDLE), |
+ busy_before_sync_reads_(false), |
weak_factory_(this) { |
// Check that reads and writes have a contiguous set of sequence numbers |
// starting from 0 and working their way up, with no repeats and skipping |
@@ -427,6 +439,20 @@ bool SequencedSocketData::AllWriteDataConsumed() const { |
return helper_.AllWriteDataConsumed(); |
} |
+bool SequencedSocketData::IsIdle() const { |
+ // If |busy_before_sync_reads_| is not set, always considered idle. If |
+ // no reads left, or the next operation is a write, also consider it idle. |
+ if (!busy_before_sync_reads_ || helper_.AllReadDataConsumed() || |
+ helper_.PeekRead().sequence_number != sequence_number_) { |
+ return true; |
+ } |
+ |
+ // If the next operation is synchronous read, treat the socket as not idle. |
+ if (helper_.PeekRead().mode == SYNCHRONOUS) |
+ return false; |
+ return true; |
+} |
+ |
bool SequencedSocketData::IsReadPaused() { |
return read_state_ == PAUSED; |
} |
@@ -940,11 +966,14 @@ MockTCPClientSocket::MockTCPClientSocket(const AddressList& addresses, |
data_->Reset(); |
} |
-MockTCPClientSocket::~MockTCPClientSocket() {} |
+MockTCPClientSocket::~MockTCPClientSocket() { |
+ if (data_) |
+ data_->set_socket(nullptr); |
+} |
int MockTCPClientSocket::Read(IOBuffer* buf, int buf_len, |
const CompletionCallback& callback) { |
- if (!connected_) |
+ if (!connected_ || !data_) |
return ERR_UNEXPECTED; |
// If the buffer is already in use, a read is already in progress! |
@@ -986,7 +1015,7 @@ int MockTCPClientSocket::Write(IOBuffer* buf, int buf_len, |
DCHECK(buf); |
DCHECK_GT(buf_len, 0); |
- if (!connected_) |
+ if (!connected_ || !data_) |
return ERR_UNEXPECTED; |
std::string data(buf->data(), buf_len); |
@@ -1024,6 +1053,9 @@ void MockTCPClientSocket::AddConnectionAttempts( |
} |
int MockTCPClientSocket::Connect(const CompletionCallback& callback) { |
+ if (!data_) |
+ return ERR_UNEXPECTED; |
+ |
if (connected_) |
return OK; |
connected_ = true; |
@@ -1055,11 +1087,15 @@ void MockTCPClientSocket::Disconnect() { |
} |
bool MockTCPClientSocket::IsConnected() const { |
+ if (!data_) |
+ return false; |
return connected_ && !peer_closed_connection_; |
} |
bool MockTCPClientSocket::IsConnectedAndIdle() const { |
- return IsConnected(); |
+ if (!data_) |
+ return false; |
+ return IsConnected() && data_->IsIdle(); |
} |
int MockTCPClientSocket::GetPeerAddress(IPEndPoint* address) const { |
@@ -1087,6 +1123,10 @@ bool MockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) { |
} |
void MockTCPClientSocket::OnReadComplete(const MockRead& data) { |
+ // If |data_| has been destroyed, safest to just do nothing. |
+ if (!data_) |
+ return; |
+ |
// There must be a read pending. |
DCHECK(pending_read_buf_.get()); |
// You can't complete a read with another ERR_IO_PENDING status code. |
@@ -1107,6 +1147,10 @@ void MockTCPClientSocket::OnReadComplete(const MockRead& data) { |
} |
void MockTCPClientSocket::OnWriteComplete(int rv) { |
+ // If |data_| has been destroyed, safest to just do nothing. |
+ if (!data_) |
+ return; |
+ |
// There must be a read pending. |
DCHECK(!pending_write_callback_.is_null()); |
CompletionCallback callback = pending_write_callback_; |
@@ -1114,10 +1158,18 @@ void MockTCPClientSocket::OnWriteComplete(int rv) { |
} |
void MockTCPClientSocket::OnConnectComplete(const MockConnect& data) { |
+ // If |data_| has been destroyed, safest to just do nothing. |
+ if (!data_) |
+ return; |
+ |
CompletionCallback callback = pending_connect_callback_; |
RunCallback(callback, data.result); |
} |
+void MockTCPClientSocket::OnDataProviderDestroyed() { |
+ data_ = nullptr; |
+} |
+ |
int MockTCPClientSocket::CompleteRead() { |
DCHECK(pending_read_buf_.get()); |
DCHECK(pending_read_buf_len_ > 0); |
@@ -1503,6 +1555,10 @@ bool MockSSLClientSocket::IsConnected() const { |
return transport_->socket()->IsConnected(); |
} |
+bool MockSSLClientSocket::IsConnectedAndIdle() const { |
+ return transport_->socket()->IsConnectedAndIdle(); |
+} |
+ |
bool MockSSLClientSocket::WasEverUsed() const { |
return transport_->socket()->WasEverUsed(); |
} |
@@ -1575,12 +1631,15 @@ MockUDPClientSocket::MockUDPClientSocket(SocketDataProvider* data, |
peer_addr_ = data->connect_data().peer_addr; |
} |
-MockUDPClientSocket::~MockUDPClientSocket() {} |
+MockUDPClientSocket::~MockUDPClientSocket() { |
+ if (data_) |
+ data_->set_socket(nullptr); |
+} |
int MockUDPClientSocket::Read(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) { |
- if (!connected_) |
+ if (!connected_ || !data_) |
return ERR_UNEXPECTED; |
// If the buffer is already in use, a read is already in progress! |
@@ -1611,7 +1670,7 @@ int MockUDPClientSocket::Write(IOBuffer* buf, int buf_len, |
DCHECK(buf); |
DCHECK_GT(buf_len, 0); |
- if (!connected_) |
+ if (!connected_ || !data_) |
return ERR_UNEXPECTED; |
std::string data(buf->data(), buf_len); |
@@ -1665,12 +1724,17 @@ int MockUDPClientSocket::BindToNetwork( |
} |
int MockUDPClientSocket::Connect(const IPEndPoint& address) { |
+ if (!data_) |
+ return ERR_UNEXPECTED; |
connected_ = true; |
peer_addr_ = address; |
return data_->connect_data().result; |
} |
void MockUDPClientSocket::OnReadComplete(const MockRead& data) { |
+ if (!data_) |
+ return; |
+ |
// There must be a read pending. |
DCHECK(pending_read_buf_.get()); |
// You can't complete a read with another ERR_IO_PENDING status code. |
@@ -1691,6 +1755,9 @@ void MockUDPClientSocket::OnReadComplete(const MockRead& data) { |
} |
void MockUDPClientSocket::OnWriteComplete(int rv) { |
+ if (!data_) |
+ return; |
+ |
// There must be a read pending. |
DCHECK(!pending_write_callback_.is_null()); |
CompletionCallback callback = pending_write_callback_; |
@@ -1701,6 +1768,10 @@ void MockUDPClientSocket::OnConnectComplete(const MockConnect& data) { |
NOTIMPLEMENTED(); |
} |
+void MockUDPClientSocket::OnDataProviderDestroyed() { |
+ data_ = nullptr; |
+} |
+ |
int MockUDPClientSocket::CompleteRead() { |
DCHECK(pending_read_buf_.get()); |
DCHECK(pending_read_buf_len_ > 0); |