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

Unified Diff: trunk/src/net/spdy/spdy_session.cc

Issue 310563002: Revert 273680 "Defer SpdySession destruction to support closing ..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 7 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
« no previous file with comments | « trunk/src/net/spdy/spdy_session.h ('k') | trunk/src/net/spdy/spdy_session_pool.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: trunk/src/net/spdy/spdy_session.cc
===================================================================
--- trunk/src/net/spdy/spdy_session.cc (revision 274100)
+++ trunk/src/net/spdy/spdy_session.cc (working copy)
@@ -527,7 +527,8 @@
SpdySession::~SpdySession() {
CHECK(!in_io_loop_);
- DcheckDraining();
+ DCHECK(!pool_);
+ DcheckClosed();
// TODO(akalin): Check connection->is_initialized() instead. This
// requires re-working CreateFakeSpdySession(), though.
@@ -601,7 +602,7 @@
NetLog::TYPE_SPDY_SESSION_INITIALIZED,
connection_->socket()->NetLog().source().ToEventParametersCallback());
- DCHECK_EQ(availability_state_, STATE_AVAILABLE);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
connection_->AddHigherLayeredPool(this);
if (enable_sending_initial_data_)
SendInitialData();
@@ -618,7 +619,7 @@
if (!verify_domain_authentication_)
return true;
- if (availability_state_ == STATE_DRAINING)
+ if (availability_state_ == STATE_CLOSED)
return false;
SSLInfo ssl_info;
@@ -644,7 +645,8 @@
stream->reset();
- if (availability_state_ == STATE_DRAINING)
+ // TODO(akalin): Add unit test exercising this code path.
+ if (availability_state_ == STATE_CLOSED)
return ERR_CONNECTION_CLOSED;
Error err = TryAccessStream(url);
@@ -664,16 +666,17 @@
// another being closed due to received data.
Error SpdySession::TryAccessStream(const GURL& url) {
- CHECK_NE(availability_state_, STATE_DRAINING);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
if (is_secure_ && certificate_error_code_ != OK &&
(url.SchemeIs("https") || url.SchemeIs("wss"))) {
RecordProtocolErrorHistogram(
PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
- DoDrainSession(
+ CloseSessionResult result = DoCloseSession(
static_cast<Error>(certificate_error_code_),
"Tried to get SPDY stream for secure content over an unauthenticated "
"session.");
+ DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED);
return ERR_SPDY_PROTOCOL_ERROR;
}
return OK;
@@ -687,7 +690,8 @@
if (availability_state_ == STATE_GOING_AWAY)
return ERR_FAILED;
- if (availability_state_ == STATE_DRAINING)
+ // TODO(akalin): Add unit test exercising this code path.
+ if (availability_state_ == STATE_CLOSED)
return ERR_CONNECTION_CLOSED;
Error err = TryAccessStream(request->url());
@@ -717,7 +721,8 @@
if (availability_state_ == STATE_GOING_AWAY)
return ERR_FAILED;
- if (availability_state_ == STATE_DRAINING)
+ // TODO(akalin): Add unit test exercising this code path.
+ if (availability_state_ == STATE_CLOSED)
return ERR_CONNECTION_CLOSED;
Error err = TryAccessStream(request.url());
@@ -733,9 +738,10 @@
UMA_HISTOGRAM_BOOLEAN("Net.SpdySession.CreateStreamWithSocketConnected",
connection_->socket()->IsConnected());
if (!connection_->socket()->IsConnected()) {
- DoDrainSession(
+ CloseSessionResult result = DoCloseSession(
ERR_CONNECTION_CLOSED,
"Tried to create SPDY stream for a closed socket connection.");
+ DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED);
return ERR_CONNECTION_CLOSED;
}
}
@@ -876,12 +882,17 @@
bool SpdySession::CloseOneIdleConnection() {
CHECK(!in_io_loop_);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
DCHECK(pool_);
- if (active_streams_.empty()) {
- DoDrainSession(ERR_CONNECTION_CLOSED, "Closing idle connection.");
+ if (!active_streams_.empty())
+ return false;
+ CloseSessionResult result =
+ DoCloseSession(ERR_CONNECTION_CLOSED, "Closing one idle connection.");
+ if (result != SESSION_CLOSED_AND_REMOVED) {
+ NOTREACHED();
+ return false;
}
- // Return false as the socket wasn't immediately closed.
- return false;
+ return true;
}
void SpdySession::EnqueueStreamWrite(
@@ -934,7 +945,8 @@
IOBuffer* data,
int len,
SpdyDataFlags flags) {
- if (availability_state_ == STATE_DRAINING) {
+ if (availability_state_ == STATE_CLOSED) {
+ NOTREACHED();
return scoped_ptr<SpdyBuffer>();
}
@@ -1123,13 +1135,22 @@
if (owned_stream->type() == SPDY_PUSH_STREAM)
unclaimed_pushed_streams_.erase(owned_stream->url());
+ base::WeakPtr<SpdySession> weak_this = GetWeakPtr();
+
DeleteStream(owned_stream.Pass(), status);
- MaybeFinishGoingAway();
+ if (!weak_this)
+ return;
+
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
// If there are no active streams and the socket pool is stalled, close the
// session to free up a socket slot.
if (active_streams_.empty() && connection_->IsPoolStalled()) {
- DoDrainSession(ERR_CONNECTION_CLOSED, "Closing idle connection.");
+ CloseSessionResult result =
+ DoCloseSession(ERR_CONNECTION_CLOSED, "Closing idle connection.");
+ CHECK_NE(result, SESSION_ALREADY_CLOSED);
}
}
@@ -1174,21 +1195,31 @@
void SpdySession::PumpReadLoop(ReadState expected_read_state, int result) {
CHECK(!in_io_loop_);
- if (availability_state_ == STATE_DRAINING) {
+ CHECK_NE(availability_state_, STATE_CLOSED);
+ CHECK_EQ(read_state_, expected_read_state);
+
+ result = DoReadLoop(expected_read_state, result);
+
+ if (availability_state_ == STATE_CLOSED) {
+ CHECK_EQ(result, error_on_close_);
+ CHECK_LT(error_on_close_, ERR_IO_PENDING);
+ RemoveFromPool();
return;
}
- ignore_result(DoReadLoop(expected_read_state, result));
+
+ CHECK(result == OK || result == ERR_IO_PENDING);
}
int SpdySession::DoReadLoop(ReadState expected_read_state, int result) {
CHECK(!in_io_loop_);
+ CHECK_NE(availability_state_, STATE_CLOSED);
CHECK_EQ(read_state_, expected_read_state);
in_io_loop_ = true;
int bytes_read_without_yielding = 0;
- // Loop until the session is draining, the read becomes blocked, or
+ // Loop until the session is closed, the read becomes blocked, or
// the read limit is exceeded.
while (true) {
switch (read_state_) {
@@ -1206,8 +1237,11 @@
break;
}
- if (availability_state_ == STATE_DRAINING)
+ if (availability_state_ == STATE_CLOSED) {
+ CHECK_EQ(result, error_on_close_);
+ CHECK_LT(result, ERR_IO_PENDING);
break;
+ }
if (result == ERR_IO_PENDING)
break;
@@ -1231,6 +1265,7 @@
int SpdySession::DoRead() {
CHECK(in_io_loop_);
+ CHECK_NE(availability_state_, STATE_CLOSED);
CHECK(connection_);
CHECK(connection_->socket());
@@ -1244,6 +1279,7 @@
int SpdySession::DoReadComplete(int result) {
CHECK(in_io_loop_);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
// Parse a frame. For now this code requires that the frame fit into our
// buffer (kReadBufferSize).
@@ -1252,13 +1288,20 @@
if (result == 0) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.EOF",
total_bytes_received_, 1, 100000000, 50);
- DoDrainSession(ERR_CONNECTION_CLOSED, "Connection closed");
-
+ CloseSessionResult close_session_result =
+ DoCloseSession(ERR_CONNECTION_CLOSED, "Connection closed");
+ DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED);
+ DCHECK_EQ(availability_state_, STATE_CLOSED);
+ DCHECK_EQ(error_on_close_, ERR_CONNECTION_CLOSED);
return ERR_CONNECTION_CLOSED;
}
if (result < 0) {
- DoDrainSession(static_cast<Error>(result), "result is < 0.");
+ CloseSessionResult close_session_result =
+ DoCloseSession(static_cast<Error>(result), "result is < 0.");
+ DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED);
+ DCHECK_EQ(availability_state_, STATE_CLOSED);
+ DCHECK_EQ(error_on_close_, result);
return result;
}
CHECK_LE(result, kReadBufferSize);
@@ -1273,8 +1316,9 @@
result -= bytes_processed;
data += bytes_processed;
- if (availability_state_ == STATE_DRAINING) {
- return ERR_CONNECTION_CLOSED;
+ if (availability_state_ == STATE_CLOSED) {
+ DCHECK_LT(error_on_close_, ERR_IO_PENDING);
+ return error_on_close_;
}
DCHECK_EQ(buffered_spdy_framer_->error_code(), SpdyFramer::SPDY_NO_ERROR);
@@ -1286,19 +1330,24 @@
void SpdySession::PumpWriteLoop(WriteState expected_write_state, int result) {
CHECK(!in_io_loop_);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
DCHECK_EQ(write_state_, expected_write_state);
- DoWriteLoop(expected_write_state, result);
+ result = DoWriteLoop(expected_write_state, result);
- if (availability_state_ == STATE_DRAINING && !in_flight_write_ &&
- write_queue_.IsEmpty()) {
- pool_->RemoveUnavailableSession(GetWeakPtr()); // Destroys |this|.
+ if (availability_state_ == STATE_CLOSED) {
+ DCHECK_EQ(result, error_on_close_);
+ DCHECK_LT(error_on_close_, ERR_IO_PENDING);
+ RemoveFromPool();
return;
}
+
+ DCHECK(result == OK || result == ERR_IO_PENDING);
}
int SpdySession::DoWriteLoop(WriteState expected_write_state, int result) {
CHECK(!in_io_loop_);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
DCHECK_NE(write_state_, WRITE_STATE_IDLE);
DCHECK_EQ(write_state_, expected_write_state);
@@ -1320,6 +1369,12 @@
break;
}
+ if (availability_state_ == STATE_CLOSED) {
+ DCHECK_EQ(result, error_on_close_);
+ DCHECK_LT(result, ERR_IO_PENDING);
+ break;
+ }
+
if (write_state_ == WRITE_STATE_IDLE) {
DCHECK_EQ(result, ERR_IO_PENDING);
break;
@@ -1337,6 +1392,7 @@
int SpdySession::DoWrite() {
CHECK(in_io_loop_);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
DCHECK(buffered_spdy_framer_);
if (in_flight_write_) {
@@ -1400,6 +1456,7 @@
int SpdySession::DoWriteComplete(int result) {
CHECK(in_io_loop_);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
DCHECK_NE(result, ERR_IO_PENDING);
DCHECK_GT(in_flight_write_->GetRemainingSize(), 0u);
@@ -1411,9 +1468,12 @@
in_flight_write_frame_type_ = DATA;
in_flight_write_frame_size_ = 0;
in_flight_write_stream_.reset();
- write_state_ = WRITE_STATE_DO_WRITE;
- DoDrainSession(static_cast<Error>(result), "Write error");
- return OK;
+ CloseSessionResult close_session_result =
+ DoCloseSession(static_cast<Error>(result), "Write error");
+ DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED);
+ DCHECK_EQ(availability_state_, STATE_CLOSED);
+ DCHECK_EQ(error_on_close_, result);
+ return result;
}
// It should not be possible to have written more bytes than our
@@ -1457,11 +1517,13 @@
#endif
}
-void SpdySession::DcheckDraining() const {
+void SpdySession::DcheckClosed() const {
DcheckGoingAway();
- DCHECK_EQ(availability_state_, STATE_DRAINING);
+ DCHECK_EQ(availability_state_, STATE_CLOSED);
+ DCHECK_LT(error_on_close_, ERR_IO_PENDING);
DCHECK(active_streams_.empty());
DCHECK(unclaimed_pushed_streams_.empty());
+ DCHECK(write_queue_.IsEmpty());
}
void SpdySession::StartGoingAway(SpdyStreamId last_good_stream_id,
@@ -1511,22 +1573,22 @@
}
void SpdySession::MaybeFinishGoingAway() {
- if (active_streams_.empty() && availability_state_ == STATE_GOING_AWAY) {
- DoDrainSession(OK, "Finished going away");
+ DcheckGoingAway();
+ if (active_streams_.empty() && availability_state_ != STATE_CLOSED) {
+ CloseSessionResult result =
+ DoCloseSession(ERR_CONNECTION_CLOSED, "Finished going away");
+ CHECK_NE(result, SESSION_ALREADY_CLOSED);
}
}
-void SpdySession::DoDrainSession(Error err, const std::string& description) {
- if (availability_state_ == STATE_DRAINING) {
- return;
- }
- MakeUnavailable();
+SpdySession::CloseSessionResult SpdySession::DoCloseSession(
+ Error err,
+ const std::string& description) {
+ CHECK_LT(err, ERR_IO_PENDING);
- // TODO(jgraettinger): If draining with an |err|, enqueue a GOAWAY frame here.
+ if (availability_state_ == STATE_CLOSED)
+ return SESSION_ALREADY_CLOSED;
- availability_state_ = STATE_DRAINING;
- error_on_close_ = err;
-
net_log_.AddEvent(
NetLog::TYPE_SPDY_SESSION_CLOSE,
base::Bind(&NetLogSpdySessionCloseCallback, err, &description));
@@ -1535,11 +1597,34 @@
UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors",
total_bytes_received_, 1, 100000000, 50);
+ CHECK(pool_);
+ if (availability_state_ != STATE_GOING_AWAY)
+ pool_->MakeSessionUnavailable(GetWeakPtr());
+
+ availability_state_ = STATE_CLOSED;
+ error_on_close_ = err;
+
StartGoingAway(0, err);
- DcheckDraining();
- MaybePostWriteLoop();
+ write_queue_.Clear();
+
+ DcheckClosed();
+
+ if (in_io_loop_)
+ return SESSION_CLOSED_BUT_NOT_REMOVED;
+
+ RemoveFromPool();
+ return SESSION_CLOSED_AND_REMOVED;
}
+void SpdySession::RemoveFromPool() {
+ DcheckClosed();
+ CHECK(pool_);
+
+ SpdySessionPool* pool = pool_;
+ pool_ = NULL;
+ pool->RemoveUnavailableSession(GetWeakPtr());
+}
+
void SpdySession::LogAbandonedStream(SpdyStream* stream, Error status) {
DCHECK(stream);
std::string description = base::StringPrintf(
@@ -1576,13 +1661,15 @@
void SpdySession::CloseSessionOnError(Error err,
const std::string& description) {
- DoDrainSession(err, description);
+ // We may be called from anywhere, so we can't expect a particular
+ // return value.
+ ignore_result(DoCloseSession(err, description));
}
void SpdySession::MakeUnavailable() {
- CHECK_NE(availability_state_, STATE_DRAINING);
- if (availability_state_ == STATE_AVAILABLE) {
+ if (availability_state_ < STATE_GOING_AWAY) {
availability_state_ = STATE_GOING_AWAY;
+ DCHECK(pool_);
pool_->MakeSessionUnavailable(GetWeakPtr());
}
}
@@ -1691,16 +1778,14 @@
SpdyFrameType frame_type,
scoped_ptr<SpdyBufferProducer> producer,
const base::WeakPtr<SpdyStream>& stream) {
- if (availability_state_ == STATE_DRAINING)
+ if (availability_state_ == STATE_CLOSED)
return;
+ bool was_idle = write_queue_.IsEmpty();
write_queue_.Enqueue(priority, frame_type, producer.Pass(), stream);
- MaybePostWriteLoop();
-}
-
-void SpdySession::MaybePostWriteLoop() {
if (write_state_ == WRITE_STATE_IDLE) {
- CHECK(!in_flight_write_);
+ DCHECK(was_idle);
+ DCHECK(!in_flight_write_);
write_state_ = WRITE_STATE_DO_WRITE;
base::MessageLoop::current()->PostTask(
FROM_HERE,
@@ -1744,10 +1829,26 @@
}
write_queue_.RemovePendingWritesForStream(stream->GetWeakPtr());
+
+ // |stream->OnClose()| may end up closing |this|, so detect that.
+ base::WeakPtr<SpdySession> weak_this = GetWeakPtr();
+
stream->OnClose(status);
- if (availability_state_ == STATE_AVAILABLE) {
- ProcessPendingStreamRequests();
+ if (!weak_this)
+ return;
+
+ switch (availability_state_) {
+ case STATE_AVAILABLE:
+ ProcessPendingStreamRequests();
+ break;
+ case STATE_GOING_AWAY:
+ DcheckGoingAway();
+ MaybeFinishGoingAway();
+ break;
+ case STATE_CLOSED:
+ // Do nothing.
+ break;
}
}
@@ -1791,16 +1892,24 @@
void SpdySession::OnError(SpdyFramer::SpdyError error_code) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
RecordProtocolErrorHistogram(MapFramerErrorToProtocolError(error_code));
std::string description = base::StringPrintf(
"SPDY_ERROR error_code: %d.", error_code);
- DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, description);
+ CloseSessionResult result =
+ DoCloseSession(ERR_SPDY_PROTOCOL_ERROR, description);
+ DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
}
void SpdySession::OnStreamError(SpdyStreamId stream_id,
const std::string& description) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
ActiveStreamMap::iterator it = active_streams_.find(stream_id);
if (it == active_streams_.end()) {
// We still want to send a frame to reset the stream even if we
@@ -1818,6 +1927,9 @@
bool fin) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
ActiveStreamMap::iterator it = active_streams_.find(stream_id);
// By the time data comes in, the stream may already be inactive.
@@ -1838,6 +1950,9 @@
bool fin) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
if (data == NULL && len != 0) {
// This is notification of consumed data padding.
// TODO(jgraettinger): Properly flow padding into WINDOW_UPDATE frames.
@@ -1897,6 +2012,9 @@
void SpdySession::OnSettings(bool clear_persisted) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
if (clear_persisted)
http_server_properties_->ClearSpdySettings(host_port_pair());
@@ -1924,6 +2042,9 @@
uint32 value) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
HandleSetting(id, value);
http_server_properties_->SetSpdySetting(
host_port_pair(),
@@ -1991,6 +2112,9 @@
const SpdyHeaderBlock& headers) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
base::Time response_time = base::Time::Now();
base::TimeTicks recv_first_byte_time = time_func_();
@@ -2176,6 +2300,9 @@
const SpdyHeaderBlock& headers) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
base::Time response_time = base::Time::Now();
base::TimeTicks recv_first_byte_time = time_func_();
@@ -2223,6 +2350,9 @@
const SpdyHeaderBlock& headers) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
if (net_log().IsLogging()) {
net_log().AddEvent(
NetLog::TYPE_SPDY_SESSION_RECV_HEADERS,
@@ -2270,6 +2400,9 @@
SpdyRstStreamStatus status) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
std::string description;
net_log().AddEvent(
NetLog::TYPE_SPDY_SESSION_RST_STREAM,
@@ -2305,6 +2438,9 @@
SpdyGoAwayStatus status) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_GOAWAY,
base::Bind(&NetLogSpdyGoAwayCallback,
last_accepted_stream_id,
@@ -2323,6 +2459,9 @@
void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
net_log_.AddEvent(
NetLog::TYPE_SPDY_SESSION_PING,
base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received"));
@@ -2337,7 +2476,9 @@
--pings_in_flight_;
if (pings_in_flight_ < 0) {
RecordProtocolErrorHistogram(PROTOCOL_ERROR_UNEXPECTED_PING);
- DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, "pings_in_flight_ is < 0.");
+ CloseSessionResult result =
+ DoCloseSession(ERR_SPDY_PROTOCOL_ERROR, "pings_in_flight_ is < 0.");
+ DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
pings_in_flight_ = 0;
return;
}
@@ -2354,6 +2495,9 @@
uint32 delta_window_size) {
CHECK(in_io_loop_);
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
DCHECK_LE(delta_window_size, static_cast<uint32>(kint32max));
net_log_.AddEvent(
NetLog::TYPE_SPDY_SESSION_RECEIVED_WINDOW_UPDATE_FRAME,
@@ -2371,10 +2515,11 @@
if (delta_window_size < 1u) {
RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE);
- DoDrainSession(
+ CloseSessionResult result = DoCloseSession(
ERR_SPDY_PROTOCOL_ERROR,
"Received WINDOW_UPDATE with an invalid delta_window_size " +
- base::UintToString(delta_window_size));
+ base::UintToString(delta_window_size));
+ DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
return;
}
@@ -2432,6 +2577,7 @@
void SpdySession::SendInitialData() {
DCHECK(enable_sending_initial_data_);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
if (send_connection_header_prefix_) {
DCHECK_EQ(protocol_, kProtoSPDY4);
@@ -2497,6 +2643,8 @@
void SpdySession::SendSettings(const SettingsMap& settings) {
+ DCHECK_NE(availability_state_, STATE_CLOSED);
+
net_log_.AddEvent(
NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS,
base::Bind(&NetLogSpdySendSettingsCallback, &settings));
@@ -2625,6 +2773,7 @@
void SpdySession::CheckPingStatus(base::TimeTicks last_check_time) {
CHECK(!in_io_loop_);
+ DCHECK_NE(availability_state_, STATE_CLOSED);
// Check if we got a response back for all PINGs we had sent.
if (pings_in_flight_ == 0) {
@@ -2640,7 +2789,9 @@
if (delay.InMilliseconds() < 0 || last_activity_time_ < last_check_time) {
// Track all failed PING messages in a separate bucket.
RecordPingRTTHistogram(base::TimeDelta::Max());
- DoDrainSession(ERR_SPDY_PING_FAILED, "Failed ping.");
+ CloseSessionResult result =
+ DoCloseSession(ERR_SPDY_PING_FAILED, "Failed ping.");
+ DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED);
return;
}
@@ -2773,6 +2924,9 @@
// We can be called with |in_io_loop_| set if a write SpdyBuffer is
// deleted (e.g., a stream is closed due to incoming data).
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
if (consume_source == SpdyBuffer::DISCARD) {
@@ -2792,6 +2946,7 @@
// We can be called with |in_io_loop_| set if a SpdyBuffer is
// deleted (e.g., a stream is closed due to incoming data).
+ DCHECK_NE(availability_state_, STATE_CLOSED);
DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
DCHECK_GE(delta_window_size, 1);
@@ -2799,12 +2954,13 @@
int32 max_delta_window_size = kint32max - session_send_window_size_;
if (delta_window_size > max_delta_window_size) {
RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE);
- DoDrainSession(
+ CloseSessionResult result = DoCloseSession(
ERR_SPDY_PROTOCOL_ERROR,
"Received WINDOW_UPDATE [delta: " +
- base::IntToString(delta_window_size) +
- "] for session overflows session_send_window_size_ [current: " +
- base::IntToString(session_send_window_size_) + "]");
+ base::IntToString(delta_window_size) +
+ "] for session overflows session_send_window_size_ [current: " +
+ base::IntToString(session_send_window_size_) + "]");
+ DCHECK_NE(result, SESSION_ALREADY_CLOSED);
return;
}
@@ -2820,6 +2976,7 @@
}
void SpdySession::DecreaseSendWindowSize(int32 delta_window_size) {
+ DCHECK_NE(availability_state_, STATE_CLOSED);
DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
// We only call this method when sending a frame. Therefore,
@@ -2845,6 +3002,9 @@
// We can be called with |in_io_loop_| set if a read SpdyBuffer is
// deleted (e.g., discarded by a SpdyReadQueue).
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
DCHECK_GE(consume_size, 1u);
DCHECK_LE(consume_size, static_cast<size_t>(kint32max));
@@ -2853,6 +3013,7 @@
}
void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) {
+ DCHECK_NE(availability_state_, STATE_CLOSED);
DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
DCHECK_GE(session_unacked_recv_window_bytes_, 0);
DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_);
@@ -2885,11 +3046,12 @@
// negative. If we do, the receive window isn't being respected.
if (delta_window_size > session_recv_window_size_) {
RecordProtocolErrorHistogram(PROTOCOL_ERROR_RECEIVE_WINDOW_VIOLATION);
- DoDrainSession(
+ CloseSessionResult result = DoCloseSession(
ERR_SPDY_PROTOCOL_ERROR,
"delta_window_size is " + base::IntToString(delta_window_size) +
" in DecreaseRecvWindowSize, which is larger than the receive " +
"window size of " + base::IntToString(session_recv_window_size_));
+ DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
return;
}
@@ -2916,7 +3078,7 @@
// have to worry about streams being closed, as well as ourselves
// being closed.
- while (!IsSendStalled()) {
+ while (availability_state_ != STATE_CLOSED && !IsSendStalled()) {
size_t old_size = 0;
#if DCHECK_IS_ON
old_size = GetTotalSize(stream_send_unstall_queue_);
« no previous file with comments | « trunk/src/net/spdy/spdy_session.h ('k') | trunk/src/net/spdy/spdy_session_pool.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698