diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-15 20:46:59 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-15 20:46:59 +0000 |
commit | ecda881ba8ac8a16f6e05409ec1e57339c1c219c (patch) | |
tree | 434461c3e26abbb9318e49a9d700265efb4b2097 /net | |
parent | b8773eb4a6a8a7256801ca724f6ff8b578a9dbd4 (diff) | |
download | chromium_src-ecda881ba8ac8a16f6e05409ec1e57339c1c219c.zip chromium_src-ecda881ba8ac8a16f6e05409ec1e57339c1c219c.tar.gz chromium_src-ecda881ba8ac8a16f6e05409ec1e57339c1c219c.tar.bz2 |
[SPDY] Add in_do_loop_ sentinel variable to SpdyStream
This is to catch quickly cases where the delegate tries to close the
SpdyStream while it's being called by the SpdyStream.
Fix a test that triggers this check.
BUG=238429
Review URL: https://chromiumcodereview.appspot.com/15187002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200345 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/spdy/spdy_session_spdy3_unittest.cc | 23 | ||||
-rw-r--r-- | net/spdy/spdy_stream.cc | 12 | ||||
-rw-r--r-- | net/spdy/spdy_stream.h | 4 |
3 files changed, 31 insertions, 8 deletions
diff --git a/net/spdy/spdy_session_spdy3_unittest.cc b/net/spdy/spdy_session_spdy3_unittest.cc index a151501..7bb1b0a 100644 --- a/net/spdy/spdy_session_spdy3_unittest.cc +++ b/net/spdy/spdy_session_spdy3_unittest.cc @@ -3402,10 +3402,13 @@ class SessionClosingDelegate : public test::StreamDelegateWithBody { virtual int OnSendBody() OVERRIDE { int rv = test::StreamDelegateWithBody::OnSendBody(); if (session_to_close_) { - session_to_close_->CloseSessionOnError( - ERR_CONNECTION_CLOSED, - true, - "Closed by SessionClosingDelegate"); + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&SpdySession::CloseSessionOnError, + session_to_close_, + ERR_CONNECTION_CLOSED, + true, + "Closed by SessionClosingDelegate")); session_to_close_ = NULL; } return rv; @@ -3433,13 +3436,13 @@ TEST_F(SpdySessionSpdy3Test, SendWindowSizeIncreaseWithDeletedSession31) { ConstructSpdyPost(kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); scoped_ptr<SpdyFrame> req2( ConstructSpdyPost(kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0)); - scoped_ptr<SpdyFrame> msg2( - ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, false)); + scoped_ptr<SpdyFrame> msg1( + ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); MockWrite writes[] = { CreateMockWrite(*initial_window_update, 0), CreateMockWrite(*req1, 1), CreateMockWrite(*req2, 3), - CreateMockWrite(*msg2, 5), + CreateMockWrite(*msg1, 5), }; scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); @@ -3515,11 +3518,15 @@ TEST_F(SpdySessionSpdy3Test, SendWindowSizeIncreaseWithDeletedSession31) { EXPECT_TRUE(spdy_session_pool_->HasSession(pair_)); - // Unstall stream1, which should then close the session. + // Unstall stream1, which should then post a task to close the + // session. delegate1.set_session_to_close(session); UnstallSessionSend(session, kBodyDataSize); session = NULL; + // Run the task to close the session. + MessageLoop::current()->RunUntilIdle(); + EXPECT_FALSE(spdy_session_pool_->HasSession(pair_)); EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc index 6f97132..3f6c266 100644 --- a/net/spdy/spdy_stream.cc +++ b/net/spdy/spdy_stream.cc @@ -115,6 +115,7 @@ SpdyStream::SpdyStream(SpdySession* session, bool pushed, const BoundNetLog& net_log) : weak_ptr_factory_(this), + in_do_loop_(false), continue_buffering_data_(true), stream_id_(0), path_(path), @@ -142,6 +143,7 @@ SpdyStream::SpdyStream(SpdySession* session, } SpdyStream::~SpdyStream() { + CHECK(!in_do_loop_); UpdateHistograms(); } @@ -227,6 +229,7 @@ scoped_ptr<SpdyFrame> SpdyStream::ProduceHeaderFrame( } void SpdyStream::DetachDelegate() { + CHECK(!in_do_loop_); DCHECK(!closed()); delegate_ = NULL; Cancel(); @@ -577,6 +580,7 @@ void SpdyStream::LogStreamError(int status, const std::string& description) { } void SpdyStream::OnClose(int status) { + CHECK(!in_do_loop_); io_state_ = STATE_DONE; response_status_ = status; Delegate* delegate = delegate_; @@ -586,6 +590,7 @@ void SpdyStream::OnClose(int status) { } void SpdyStream::Cancel() { + CHECK(!in_do_loop_); if (stream_id_ != 0) { session_->ResetStream(stream_id_, priority_, RST_STREAM_CANCEL, std::string()); @@ -595,6 +600,7 @@ void SpdyStream::Cancel() { } void SpdyStream::Close() { + CHECK(!in_do_loop_); if (stream_id_ != 0) { session_->CloseActiveStream(stream_id_, OK); } else { @@ -714,6 +720,9 @@ void SpdyStream::OnGetDomainBoundCertComplete(int result) { } int SpdyStream::DoLoop(int result) { + CHECK(!in_do_loop_); + in_do_loop_ = true; + do { State state = io_state_; io_state_ = STATE_NONE; @@ -783,6 +792,9 @@ int SpdyStream::DoLoop(int result) { } while (result != ERR_IO_PENDING && io_state_ != STATE_NONE && io_state_ != STATE_OPEN); + CHECK(in_do_loop_); + in_do_loop_ = false; + return result; } diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h index 0f5f541..8ead4e6 100644 --- a/net/spdy/spdy_stream.h +++ b/net/spdy/spdy_stream.h @@ -388,6 +388,10 @@ class NET_EXPORT_PRIVATE SpdyStream { base::WeakPtrFactory<SpdyStream> weak_ptr_factory_; + // Sentinel variable used to make sure we don't get destroyed by a + // function called from DoLoop(). + bool in_do_loop_; + // There is a small period of time between when a server pushed stream is // first created, and the pushed data is replayed. Any data received during // this time should continue to be buffered. |