summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-15 20:46:59 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-15 20:46:59 +0000
commitecda881ba8ac8a16f6e05409ec1e57339c1c219c (patch)
tree434461c3e26abbb9318e49a9d700265efb4b2097 /net
parentb8773eb4a6a8a7256801ca724f6ff8b578a9dbd4 (diff)
downloadchromium_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.cc23
-rw-r--r--net/spdy/spdy_stream.cc12
-rw-r--r--net/spdy/spdy_stream.h4
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.