Bug 1073825 - http2session::cleanupstream failure. r=hurley, a=lmandel
authorPatrick McManus <mcmanus@ducksong.com>
Mon, 13 Oct 2014 11:02:08 -0400
changeset 225799 eed6613c5568
parent 225798 823ecd23138b
child 225800 9d0a16097623
push id4021
push userryanvm@gmail.com
push date2014-10-24 13:05 +0000
treeherdermozilla-beta@b185e7a13e18 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershurley, lmandel
bugs1073825
milestone34.0
Bug 1073825 - http2session::cleanupstream failure. r=hurley, a=lmandel
netwerk/protocol/http/Http2Session.cpp
netwerk/protocol/http/Http2Session.h
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -986,16 +986,29 @@ Http2Session::CleanupStream(Http2Stream 
     Close(NS_OK);
 
   if (pushSource) {
     pushSource->SetDeferCleanupOnSuccess(false);
     CleanupStream(pushSource, aResult, aResetCode);
   }
 }
 
+void
+Http2Session::CleanupStream(uint32_t aID, nsresult aResult, errorType aResetCode)
+{
+  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
+  Http2Stream *stream = mStreamIDHash.Get(aID);
+  LOG3(("Http2Session::CleanupStream %p by ID 0x%X to stream %p\n",
+        this, aID, stream));
+  if (!stream) {
+    return;
+  }
+  CleanupStream(stream, aResult, aResetCode);
+}
+
 static void RemoveStreamFromQueue(Http2Stream *aStream, nsDeque &queue)
 {
   uint32_t size = queue.GetSize();
   for (uint32_t count = 0; count < size; ++count) {
     Http2Stream *stream = static_cast<Http2Stream *>(queue.PopFront());
     if (stream != aStream)
       queue.Push(stream);
   }
@@ -2321,17 +2334,17 @@ Http2Session::WriteSegments(nsAHttpSegme
   if (mDownstreamState == PROCESSING_DATA_FRAME ||
       mDownstreamState == PROCESSING_COMPLETE_HEADERS) {
 
     // The cleanup stream should only be set while stream->WriteSegments is
     // on the stack and then cleaned up in this code block afterwards.
     MOZ_ASSERT(!mNeedsCleanup, "cleanup stream set unexpectedly");
     mNeedsCleanup = nullptr;                     /* just in case */
 
-    Http2Stream *stream = mInputFrameDataStream;
+    uint32_t streamID = mInputFrameDataStream->StreamID();
     mSegmentWriter = writer;
     rv = mInputFrameDataStream->WriteSegments(this, count, countWritten);
     mSegmentWriter = nullptr;
 
     mLastDataReadEpoch = mLastReadEpoch;
 
     if (SoftStreamError(rv)) {
       // This will happen when the transaction figures out it is EOF, generally
@@ -2339,23 +2352,22 @@ Http2Session::WriteSegments(nsAHttpSegme
       // otherwise the whole session would be torn down.
 
       // if we were doing PROCESSING_COMPLETE_HEADERS need to pop the state
       // back to PROCESSING_DATA_FRAME where we came from
       mDownstreamState = PROCESSING_DATA_FRAME;
 
       if (mInputFrameDataRead == mInputFrameDataSize)
         ResetDownstreamState();
-      LOG3(("Http2Session::WriteSegments session=%p stream=%p 0x%X "
+      LOG3(("Http2Session::WriteSegments session=%p id 0x%X "
             "needscleanup=%p. cleanup stream based on "
             "stream->writeSegments returning code %x\n",
-            this, stream, stream ? stream->StreamID() : 0,
-            mNeedsCleanup, rv));
-      CleanupStream(stream, NS_OK, CANCEL_ERROR);
-      MOZ_ASSERT(!mNeedsCleanup || mNeedsCleanup == stream);
+            this, streamID, mNeedsCleanup, rv));
+      CleanupStream(streamID, NS_OK, CANCEL_ERROR);
+      MOZ_ASSERT(!mNeedsCleanup || mNeedsCleanup->StreamID() == streamID);
       mNeedsCleanup = nullptr;
       return NS_OK;
     }
 
     if (mNeedsCleanup) {
       LOG3(("Http2Session::WriteSegments session=%p stream=%p 0x%X "
             "cleanup stream based on mNeedsCleanup.\n",
             this, mNeedsCleanup, mNeedsCleanup ? mNeedsCleanup->StreamID() : 0));
--- a/netwerk/protocol/http/Http2Session.h
+++ b/netwerk/protocol/http/Http2Session.h
@@ -236,16 +236,17 @@ private:
   nsresult    ReadyToProcessDataFrame(enum internalStateType);
   nsresult    UncompressAndDiscard();
   void        GeneratePing(bool);
   void        GenerateSettingsAck();
   void        GeneratePriority(uint32_t, uint8_t);
   void        GenerateRstStream(uint32_t, uint32_t);
   void        GenerateGoAway(uint32_t);
   void        CleanupStream(Http2Stream *, nsresult, errorType);
+  void        CleanupStream(uint32_t, nsresult, errorType);
   void        CloseStream(Http2Stream *, nsresult);
   void        SendHello();
   void        RemoveStreamFromQueues(Http2Stream *);
   nsresult    ParsePadding(uint8_t &, uint16_t &);
 
   void        SetWriteCallbacks();
   void        RealignOutputQueue();