bug 988421 - spdy push concurrency mismatch r=hurley
authorPatrick McManus <mcmanus@ducksong.com>
Wed, 26 Mar 2014 12:48:23 -0400
changeset 175663 e04599ab2ee3c149b49e48a716a502b54f6ba1c9
parent 175662 012fea76225f8aae6806b1ef3aa2353041a0382c
child 175664 f2c60695a6e94d19ba35bb15598af9d61c79a1c1
push id26496
push userkwierso@gmail.com
push dateFri, 28 Mar 2014 02:28:34 +0000
treeherdermozilla-central@3c09159e01da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershurley
bugs988421
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 988421 - spdy push concurrency mismatch r=hurley
netwerk/protocol/http/Http2Session.h
netwerk/protocol/http/Http2Stream.cpp
netwerk/protocol/http/SpdySession3.h
netwerk/protocol/http/SpdySession31.h
netwerk/protocol/http/SpdyStream3.cpp
netwerk/protocol/http/SpdyStream31.cpp
--- a/netwerk/protocol/http/Http2Session.h
+++ b/netwerk/protocol/http/Http2Session.h
@@ -184,16 +184,17 @@ public:
   virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
   nsresult BufferOutput(const char *, uint32_t, uint32_t *);
   void     FlushOutputQueue();
   uint32_t AmountOfOutputBuffered() { return mOutputQueueUsed - mOutputQueueSent; }
 
   uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
 
   void ConnectPushedStream(Http2Stream *stream);
+  void MaybeDecrementConcurrent(Http2Stream *stream);
 
   nsresult ConfirmTLSProfile();
 
   uint64_t Serial() { return mSerial; }
 
   void PrintDiagnostics (nsCString &log);
 
   // Streams need access to these
@@ -222,17 +223,16 @@ private:
   static const uint8_t kMagicHello[24];
 
   nsresult    ResponseHeadersComplete();
   uint32_t    GetWriteQueueSize();
   void        ChangeDownstreamState(enum internalStateType);
   void        ResetDownstreamState();
   nsresult    ReadyToProcessDataFrame(enum internalStateType);
   nsresult    UncompressAndDiscard();
-  void        MaybeDecrementConcurrent(Http2Stream *);
   void        GeneratePing(bool);
   void        GenerateSettingsAck();
   void        GeneratePriority(uint32_t, uint32_t);
   void        GenerateRstStream(uint32_t, uint32_t);
   void        GenerateGoAway(uint32_t);
   void        CleanupStream(Http2Stream *, nsresult, errorType);
   void        CloseStream(Http2Stream *, nsresult);
   void        SendHello();
--- a/netwerk/protocol/http/Http2Stream.cpp
+++ b/netwerk/protocol/http/Http2Stream.cpp
@@ -317,16 +317,23 @@ Http2Stream::ParseHttpRequestHeaders(con
     if (pushedStream) {
       LOG3(("Pushed Stream Match located id=0x%X key=%s\n",
             pushedStream->StreamID(), hashkey.get()));
       pushedStream->SetConsumerStream(this);
       mPushSource = pushedStream;
       SetSentFin(true);
       AdjustPushedPriority();
 
+      // This stream has been activated (and thus counts against the concurrency
+      // limit intentionally), but will not be registered via
+      // RegisterStreamID (below) because of the push match.
+      // Release that semaphore count immediately (instead of waiting for
+      // cleanup stream) so we can initiate more pull streams.
+      mSession->MaybeDecrementConcurrent(this);
+
       // There is probably pushed data buffered so trigger a read manually
       // as we can't rely on future network events to do it
       mSession->ConnectPushedStream(this);
       return NS_OK;
     }
   }
 
   // It is now OK to assign a streamID that we are assured will
--- a/netwerk/protocol/http/SpdySession3.h
+++ b/netwerk/protocol/http/SpdySession3.h
@@ -173,16 +173,17 @@ public:
   void TransactionHasDataToWrite(SpdyStream3 *);
 
   // an overload of nsAHttpSegementReader
   virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
 
   uint32_t GetServerInitialWindow() { return mServerInitialWindow; }
 
   void ConnectPushedStream(SpdyStream3 *stream);
+  void DecrementConcurrent(SpdyStream3 *stream);
 
   uint64_t Serial() { return mSerial; }
 
   void     PrintDiagnostics (nsCString &log);
 
   // Streams need access to these
   uint32_t SendingChunkSize() { return mSendingChunkSize; }
   uint32_t PushAllowance() { return mPushAllowance; }
@@ -200,17 +201,16 @@ private:
     PROCESSING_CONTROL_RST_STREAM
   };
 
   nsresult    ResponseHeadersComplete();
   uint32_t    GetWriteQueueSize();
   void        ChangeDownstreamState(enum stateType);
   void        ResetDownstreamState();
   nsresult    UncompressAndDiscard(uint32_t, uint32_t);
-  void        DecrementConcurrent(SpdyStream3 *);
   void        zlibInit();
   void        GeneratePing(uint32_t);
   void        GenerateRstStream(uint32_t, uint32_t);
   void        GenerateGoAway(uint32_t);
   void        CleanupStream(SpdyStream3 *, nsresult, rstReason);
   void        CloseStream(SpdyStream3 *, nsresult);
   void        GenerateSettings();
   void        RemoveStreamFromQueues(SpdyStream3 *);
--- a/netwerk/protocol/http/SpdySession31.h
+++ b/netwerk/protocol/http/SpdySession31.h
@@ -175,16 +175,17 @@ public:
   virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
   nsresult BufferOutput(const char *, uint32_t, uint32_t *);
   void     FlushOutputQueue();
   uint32_t AmountOfOutputBuffered() { return mOutputQueueUsed - mOutputQueueSent; }
 
   uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
 
   void ConnectPushedStream(SpdyStream31 *stream);
+  void DecrementConcurrent(SpdyStream31 *stream);
 
   uint64_t Serial() { return mSerial; }
 
   void     PrintDiagnostics (nsCString &log);
 
   // Streams need access to these
   uint32_t SendingChunkSize() { return mSendingChunkSize; }
   uint32_t PushAllowance() { return mPushAllowance; }
@@ -204,17 +205,16 @@ private:
     PROCESSING_CONTROL_RST_STREAM
   };
 
   nsresult    ResponseHeadersComplete();
   uint32_t    GetWriteQueueSize();
   void        ChangeDownstreamState(enum stateType);
   void        ResetDownstreamState();
   nsresult    UncompressAndDiscard(uint32_t, uint32_t);
-  void        DecrementConcurrent(SpdyStream31 *);
   void        zlibInit();
   void        GeneratePing(uint32_t);
   void        GenerateRstStream(uint32_t, uint32_t);
   void        GenerateGoAway(uint32_t);
   void        CleanupStream(SpdyStream31 *, nsresult, rstReason);
   void        CloseStream(SpdyStream31 *, nsresult);
   void        GenerateSettings();
   void        RemoveStreamFromQueues(SpdyStream31 *);
--- a/netwerk/protocol/http/SpdyStream3.cpp
+++ b/netwerk/protocol/http/SpdyStream3.cpp
@@ -306,16 +306,22 @@ SpdyStream3::ParseHttpRequestHeaders(con
 
     if (pushedStream) {
       LOG3(("Pushed Stream Match located id=0x%X key=%s\n",
             pushedStream->StreamID(), hashkey.get()));
       pushedStream->SetConsumerStream(this);
       mPushSource = pushedStream;
       mSentFinOnData = 1;
 
+      // This stream has been activated (and thus counts against the concurrency
+      // limit intentionally), but will not be registered via
+      // RegisterStreamID (below) because of the push match. Therefore the
+      // concurrency sempahore needs to be balanced.
+      mSession->DecrementConcurrent(this);
+
       // There is probably pushed data buffered so trigger a read manually
       // as we can't rely on future network events to do it
       mSession->ConnectPushedStream(this);
       return NS_OK;
     }
   }
 
   // It is now OK to assign a streamID that we are assured will
--- a/netwerk/protocol/http/SpdyStream31.cpp
+++ b/netwerk/protocol/http/SpdyStream31.cpp
@@ -311,16 +311,22 @@ SpdyStream31::ParseHttpRequestHeaders(co
 
     if (pushedStream) {
       LOG3(("Pushed Stream Match located id=0x%X key=%s\n",
             pushedStream->StreamID(), hashkey.get()));
       pushedStream->SetConsumerStream(this);
       mPushSource = pushedStream;
       mSentFinOnData = 1;
 
+      // This stream has been activated (and thus counts against the concurrency
+      // limit intentionally), but will not be registered via
+      // RegisterStreamID (below) because of the push match. Therefore the
+      // concurrency sempahore needs to be balanced.
+      mSession->DecrementConcurrent(this);
+
       // There is probably pushed data buffered so trigger a read manually
       // as we can't rely on future network events to do it
       mSession->ConnectPushedStream(this);
       return NS_OK;
     }
   }
 
   // It is now OK to assign a streamID that we are assured will