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

Unified Diff: net/socket/socket_test_util.cc

Issue 2593063003: Add Socket::ReadIfReady() (Closed)
Patch Set: Fix tests for real Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: net/socket/socket_test_util.cc
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index aeea26ad7a96fb75be2179c064f45ba5d080b8d8..433a5409af1e21676361f54735469b798d4a89f4 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -699,7 +699,8 @@ void SequencedSocketData::OnWriteComplete() {
SequencedSocketData::~SequencedSocketData() {
}
-MockClientSocketFactory::MockClientSocketFactory() {}
+MockClientSocketFactory::MockClientSocketFactory()
+ : enable_read_if_ready_(false) {}
MockClientSocketFactory::~MockClientSocketFactory() {}
@@ -743,6 +744,8 @@ MockClientSocketFactory::CreateTransportClientSocket(
SocketDataProvider* data_provider = mock_data_.GetNext();
std::unique_ptr<MockTCPClientSocket> socket(
new MockTCPClientSocket(addresses, net_log, data_provider));
+ if (enable_read_if_ready_)
+ socket->set_enable_read_if_ready(enable_read_if_ready_);
return std::move(socket);
}
@@ -882,7 +885,10 @@ MockTCPClientSocket::MockTCPClientSocket(const AddressList& addresses,
peer_closed_connection_(false),
pending_read_buf_(NULL),
pending_read_buf_len_(0),
- was_used_to_convey_data_(false) {
+ was_used_to_convey_data_(false),
+ enable_read_if_ready_(false),
+ pending_read_type_(NONE),
+ weak_factory_(this) {
DCHECK(data_);
peer_addr_ = data->connect_data().peer_addr;
data_->Initialize(this);
@@ -895,41 +901,31 @@ MockTCPClientSocket::~MockTCPClientSocket() {
int MockTCPClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
- if (!connected_ || !data_)
- return ERR_UNEXPECTED;
-
// If the buffer is already in use, a read is already in progress!
DCHECK(!pending_read_buf_);
davidben 2017/02/01 22:25:57 DCHECK_EQ(NONE, pending_read_type_); to match?
xunjieli 2017/02/03 16:35:33 Acknowledged. After applying the suggested Read()/
- // Store our async IO data.
- pending_read_buf_ = buf;
- pending_read_buf_len_ = buf_len;
- pending_read_callback_ = callback;
+ int rv = ReadCommon(buf, buf_len, callback, /*use_read_if_ready=*/false);
+ if (rv != ERR_IO_PENDING)
+ return rv;
+ pending_read_type_ = READ;
+ return ERR_IO_PENDING;
+}
- if (need_read_data_) {
- read_data_ = data_->OnRead();
- if (read_data_.result == ERR_CONNECTION_CLOSED) {
- // This MockRead is just a marker to instruct us to set
- // peer_closed_connection_.
- peer_closed_connection_ = true;
- }
- if (read_data_.result == ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) {
- // This MockRead is just a marker to instruct us to set
- // peer_closed_connection_. Skip it and get the next one.
- read_data_ = data_->OnRead();
- peer_closed_connection_ = true;
- }
- // ERR_IO_PENDING means that the SocketDataProvider is taking responsibility
- // to complete the async IO manually later (via OnReadComplete).
- if (read_data_.result == ERR_IO_PENDING) {
- // We need to be using async IO in this case.
- DCHECK(!callback.is_null());
- return ERR_IO_PENDING;
- }
- need_read_data_ = false;
- }
+int MockTCPClientSocket::ReadIfReady(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ DCHECK_EQ(NONE, pending_read_type_);
- return CompleteRead();
+ if (!enable_read_if_ready_)
+ return ERR_READ_IF_READY_NOT_IMPLEMENTED;
+
+ int rv = ReadCommon(buf, buf_len, callback, /*use_read_if_ready=*/false);
+ pending_read_buf_ = nullptr;
+ pending_read_buf_len_ = 0;
+ if (rv != ERR_IO_PENDING)
+ return rv;
+ pending_read_type_ = READ_IF_READY;
+ return ERR_IO_PENDING;
}
int MockTCPClientSocket::Write(IOBuffer* buf, int buf_len,
@@ -1043,12 +1039,14 @@ bool MockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
}
void MockTCPClientSocket::OnReadComplete(const MockRead& data) {
+ DCHECK_NE(NONE, pending_read_type_);
+
// If |data_| has been destroyed, safest to just do nothing.
if (!data_)
return;
// There must be a read pending.
- DCHECK(pending_read_buf_.get());
+ DCHECK(!pending_read_callback_.is_null());
// You can't complete a read with another ERR_IO_PENDING status code.
DCHECK_NE(ERR_IO_PENDING, data.result);
// Since we've been waiting for data, need_read_data_ should be true.
@@ -1057,13 +1055,18 @@ void MockTCPClientSocket::OnReadComplete(const MockRead& data) {
read_data_ = data;
need_read_data_ = false;
+ CompletionCallback callback = pending_read_callback_;
+ pending_read_callback_.Reset();
+
// The caller is simulating that this IO completes right now. Don't
// let CompleteRead() schedule a callback.
read_data_.mode = SYNCHRONOUS;
-
- CompletionCallback callback = pending_read_callback_;
- int rv = CompleteRead();
- RunCallback(callback, rv);
+ if (pending_read_type_ == READ_IF_READY) {
+ RunReadCallback(callback, read_data_.result > 0 ? OK : read_data_.result);
+ } else {
+ int rv = CompleteRead(pending_read_type_);
+ RunReadCallback(callback, rv);
+ }
}
void MockTCPClientSocket::OnWriteComplete(int rv) {
@@ -1090,12 +1093,62 @@ void MockTCPClientSocket::OnDataProviderDestroyed() {
data_ = nullptr;
}
-int MockTCPClientSocket::CompleteRead() {
+int MockTCPClientSocket::ReadCommon(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ bool use_read_if_ready) {
davidben 2017/02/01 22:25:57 This parameter doesn't seem to be used. Did you me
xunjieli 2017/02/03 16:35:33 Acknowledged. After applying the suggested Read()/
+ if (!connected_ || !data_)
+ return ERR_UNEXPECTED;
+
+ // If the buffer is already in use, a read is already in progress!
+ DCHECK(!pending_read_buf_);
+ DCHECK_EQ(NONE, pending_read_type_);
+
+ // Store our async IO data.
+ pending_read_buf_ = buf;
+ pending_read_buf_len_ = buf_len;
+ pending_read_callback_ = callback;
+
+ if (need_read_data_) {
+ read_data_ = data_->OnRead();
+ if (read_data_.result == ERR_CONNECTION_CLOSED) {
+ // This MockRead is just a marker to instruct us to set
+ // peer_closed_connection_.
+ peer_closed_connection_ = true;
+ }
+ if (read_data_.result == ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) {
+ // This MockRead is just a marker to instruct us to set
+ // peer_closed_connection_. Skip it and get the next one.
+ read_data_ = data_->OnRead();
+ peer_closed_connection_ = true;
+ }
+ // ERR_IO_PENDING means that the SocketDataProvider is taking responsibility
+ // to complete the async IO manually later (via OnReadComplete).
+ if (read_data_.result == ERR_IO_PENDING) {
+ // We need to be using async IO in this case.
+ DCHECK(!callback.is_null());
+ return ERR_IO_PENDING;
+ }
+ need_read_data_ = false;
+ }
+
+ return CompleteRead(false);
+}
+
+int MockTCPClientSocket::CompleteRead(bool read_if_ready_used) {
DCHECK(pending_read_buf_.get());
DCHECK(pending_read_buf_len_ > 0);
was_used_to_convey_data_ = true;
+ if (read_if_ready_used && read_data_.mode == ASYNC) {
+ CompletionCallback callback = pending_read_callback_;
+ pending_read_callback_.Reset();
+ DCHECK(!callback.is_null());
+ RunReadCallbackAsync(callback,
+ read_data_.result > 0 ? OK : read_data_.result);
+ return ERR_IO_PENDING;
+ }
// Save the pending async IO data and reset our |pending_| state.
scoped_refptr<IOBuffer> buf = pending_read_buf_;
int buf_len = pending_read_buf_len_;
@@ -1123,12 +1176,26 @@ int MockTCPClientSocket::CompleteRead() {
if (read_data_.mode == ASYNC) {
DCHECK(!callback.is_null());
- RunCallbackAsync(callback, result);
+ RunReadCallbackAsync(callback, result);
return ERR_IO_PENDING;
}
return result;
}
+void MockTCPClientSocket::RunReadCallback(const CompletionCallback& callback,
+ int result) {
+ pending_read_type_ = NONE;
+ MockClientSocket::RunCallback(callback, result);
+}
+
+void MockTCPClientSocket::RunReadCallbackAsync(
+ const CompletionCallback& callback,
+ int result) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&MockTCPClientSocket::RunReadCallback,
+ weak_factory_.GetWeakPtr(), callback, result));
+}
+
// static
void MockSSLClientSocket::ConnectCallback(
MockSSLClientSocket* ssl_client_socket,
@@ -1164,6 +1231,12 @@ int MockSSLClientSocket::Read(IOBuffer* buf, int buf_len,
return transport_->socket()->Read(buf, buf_len, callback);
}
+int MockSSLClientSocket::ReadIfReady(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ return transport_->socket()->ReadIfReady(buf, buf_len, callback);
+}
+
int MockSSLClientSocket::Write(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
return transport_->socket()->Write(buf, buf_len, callback);

Powered by Google App Engine
This is Rietveld 408576698