bug 955161 - spdy session sometimes shutdown when gecko cancels a sub transaction r=hurley a=lsblakk
authorPatrick McManus <mcmanus@ducksong.com>
Tue, 07 Jan 2014 20:18:56 -0500
changeset 175594 2287f28392566e4192b217a55a79c79264e99c8d
parent 175593 54f62d5771bf3051956d5b4cc266bc3816e76aa9
child 175595 9eca0b9912f10acfff12ae44277656dd83ebdbe1
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershurley, lsblakk
bugs955161
milestone28.0a2
bug 955161 - spdy session sometimes shutdown when gecko cancels a sub transaction r=hurley a=lsblakk
netwerk/protocol/http/ASpdySession.h
netwerk/protocol/http/SpdySession3.cpp
netwerk/protocol/http/SpdySession31.cpp
--- a/netwerk/protocol/http/ASpdySession.h
+++ b/netwerk/protocol/http/ASpdySession.h
@@ -35,16 +35,23 @@ public:
   const static uint32_t kSendingChunkSize = 4096;
   const static uint32_t kTCPSendBufferSize = 131072;
 
   // until we have an API that can push back on receiving data (right now
   // WriteSegments is obligated to accept data and buffer) there is no
   // reason to throttle with the rwin other than in server push
   // scenarios.
   const static uint32_t kInitialRwin = 256 * 1024 * 1024;
+
+  bool SoftStreamError(nsresult code)
+  {
+    return (code == NS_BASE_STREAM_CLOSED || code == NS_BINDING_FAILED ||
+            code == NS_BINDING_ABORTED || code == NS_BINDING_REDIRECTED ||
+            code == NS_BINDING_RETARGETED);
+  }
 };
 
 // this is essentially a single instantiation as a member of nsHttpHandler.
 // It could be all static except using static ctors of XPCOM objects is a
 // bad idea.
 class SpdyInformation
 {
 public:
--- a/netwerk/protocol/http/SpdySession3.cpp
+++ b/netwerk/protocol/http/SpdySession3.cpp
@@ -2018,32 +2018,33 @@ SpdySession3::WriteSegments(nsAHttpSegme
     mNeedsCleanup = nullptr;                     /* just in case */
 
     mSegmentWriter = writer;
     rv = mInputFrameDataStream->WriteSegments(this, count, countWritten);
     mSegmentWriter = nullptr;
 
     mLastDataReadEpoch = mLastReadEpoch;
 
-    if (rv == NS_BASE_STREAM_CLOSED) {
+    if (SoftStreamError(rv)) {
       // This will happen when the transaction figures out it is EOF, generally
-      // due to a content-length match being made
+      // due to a content-length match being made. Return OK from this function
+      // otherwise the whole session would be torn down.
       SpdyStream3 *stream = mInputFrameDataStream;
 
       // 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(("SpdySession3::WriteSegments session=%p stream=%p 0x%X "
             "needscleanup=%p. cleanup stream based on "
-            "stream->writeSegments returning BASE_STREAM_CLOSED\n",
+            "stream->writeSegments returning code %X\n",
             this, stream, stream ? stream->StreamID() : 0,
-            mNeedsCleanup));
+            mNeedsCleanup, rv));
       CleanupStream(stream, NS_OK, RST_CANCEL);
       MOZ_ASSERT(!mNeedsCleanup, "double cleanup out of data frame");
       mNeedsCleanup = nullptr;                     /* just in case */
       return NS_OK;
     }
 
     if (mNeedsCleanup) {
       LOG3(("SpdySession3::WriteSegments session=%p stream=%p 0x%X "
--- a/netwerk/protocol/http/SpdySession31.cpp
+++ b/netwerk/protocol/http/SpdySession31.cpp
@@ -2080,32 +2080,33 @@ SpdySession31::WriteSegments(nsAHttpSegm
     mNeedsCleanup = nullptr;                     /* just in case */
 
     mSegmentWriter = writer;
     rv = mInputFrameDataStream->WriteSegments(this, count, countWritten);
     mSegmentWriter = nullptr;
 
     mLastDataReadEpoch = mLastReadEpoch;
 
-    if (rv == NS_BASE_STREAM_CLOSED) {
+    if (SoftStreamError(rv)) {
       // This will happen when the transaction figures out it is EOF, generally
-      // due to a content-length match being made
+      // due to a content-length match being made. Return OK from this function
+      // otherwise the whole session would be torn down.
       SpdyStream31 *stream = mInputFrameDataStream;
 
       // 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(("SpdySession31::WriteSegments session=%p stream=%p 0x%X "
             "needscleanup=%p. cleanup stream based on "
-            "stream->writeSegments returning BASE_STREAM_CLOSED\n",
+            "stream->writeSegments returning code %X\n",
             this, stream, stream ? stream->StreamID() : 0,
-            mNeedsCleanup));
+            mNeedsCleanup, rv));
       CleanupStream(stream, NS_OK, RST_CANCEL);
       MOZ_ASSERT(!mNeedsCleanup, "double cleanup out of data frame");
       mNeedsCleanup = nullptr;                     /* just in case */
       return NS_OK;
     }
 
     if (mNeedsCleanup) {
       LOG3(("SpdySession31::WriteSegments session=%p stream=%p 0x%X "