Commit c182846f authored by xunjieli's avatar xunjieli Committed by Commit bot

Release SpdySession socket read buffer

This CL makes the following changes:

(1) Make SpdySession use Socket::ReadIfReady(). This new behavior is
    hidden behind a field trial flag, SocketReadIfReady.
(2) Make SpdySession lazily allocate |read_buffer| on demand.
(3) Make SpdySession release |read_buffer| when Read() completes or
    when ReadIfReady() cannot be completed synchronously.

Re-allocating an 8KiB buffer should be cheap, see more discussion
at https://groups.google.com/a/chromium.org/d/msg/project-trim/QtliUsApxyk/AOSnyuY7CgAJ

BUG=690915

Review-Url: https://codereview.chromium.org/2734933002
Cr-Commit-Position: refs/heads/master@{#455770}
parent 9b88406d
......@@ -740,7 +740,6 @@ SpdySession::SpdySession(const SpdySessionKey& spdy_session_key,
pool_(NULL),
http_server_properties_(http_server_properties),
transport_security_state_(transport_security_state),
read_buffer_(new IOBuffer(kReadBufferSize)),
stream_hi_water_mark_(kFirstStreamId),
last_accepted_push_stream_id_(0),
unclaimed_pushed_streams_(this),
......@@ -1378,8 +1377,9 @@ size_t SpdySession::DumpMemoryStats(StreamSocket::SocketMemoryStats* stats,
connection_->DumpMemoryStats(stats);
// |connection_| is estimated in stats->total_size. |read_buffer_| is
// estimated in kReadBufferSize. TODO(xunjieli): Make them use EMU().
return stats->total_size + kReadBufferSize +
// estimated in |read_buffer_size|. TODO(xunjieli): Make them use EMU().
size_t read_buffer_size = read_buffer_ ? kReadBufferSize : 0;
return stats->total_size + read_buffer_size +
SpdyEstimateMemoryUsage(spdy_session_key_) +
SpdyEstimateMemoryUsage(pooled_aliases_) +
SpdyEstimateMemoryUsage(active_streams_) +
......@@ -1869,19 +1869,24 @@ int SpdySession::DoReadLoop(ReadState expected_read_state, int result) {
}
int SpdySession::DoRead() {
DCHECK(!read_buffer_);
CHECK(in_io_loop_);
CHECK(connection_);
CHECK(connection_->socket());
read_state_ = READ_STATE_DO_READ_COMPLETE;
int rv = ERR_READ_IF_READY_NOT_IMPLEMENTED;
read_buffer_ = new IOBuffer(kReadBufferSize);
if (base::FeatureList::IsEnabled(Socket::kReadIfReadyExperiment)) {
rv = connection_->socket()->ReadIfReady(
read_buffer_.get(), kReadBufferSize,
base::Bind(&SpdySession::PumpReadLoop, weak_factory_.GetWeakPtr(),
READ_STATE_DO_READ));
// TODO(xunjieli): Follow-up CL to release |read_buffer_|.
// https://crbug.com/690915.
if (rv == ERR_IO_PENDING) {
read_buffer_ = nullptr;
read_state_ = READ_STATE_DO_READ;
return rv;
}
}
if (rv == ERR_READ_IF_READY_NOT_IMPLEMENTED) {
// Fallback to regular Read().
......@@ -1890,12 +1895,11 @@ int SpdySession::DoRead() {
base::Bind(&SpdySession::PumpReadLoop, weak_factory_.GetWeakPtr(),
READ_STATE_DO_READ_COMPLETE));
}
if (rv == ERR_IO_PENDING)
read_state_ = READ_STATE_DO_READ;
return rv;
}
int SpdySession::DoReadComplete(int result) {
DCHECK(read_buffer_);
CHECK(in_io_loop_);
// Parse a frame. For now this code requires that the frame fit into our
......@@ -1933,6 +1937,7 @@ int SpdySession::DoReadComplete(int result) {
SpdyFramer::SPDY_NO_ERROR);
}
read_buffer_ = nullptr;
read_state_ = READ_STATE_DO_READ;
return OK;
}
......
......@@ -1019,6 +1019,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
std::unique_ptr<ClientSocketHandle> connection_;
// The read buffer used to read data from the socket.
// Non-null if there is a Read() pending.
scoped_refptr<IOBuffer> read_buffer_;
SpdyStreamId stream_hi_water_mark_; // The next stream id to use.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment