зеркало из https://github.com/mozilla/gecko-dev.git
bug 1072478 backout 28fff54451dd for 1119810 and 1119926 r=backout
--HG-- extra : rebase_source : 46e7ccae81bf27f468171c240a926d421366a33b
This commit is contained in:
Родитель
74718f3dd4
Коммит
b8b9d7491a
|
@ -166,8 +166,7 @@ Http2PushedStream::ReadSegments(nsAHttpSegmentReader *,
|
||||||
|
|
||||||
// the write side of a pushed transaction just involves manipulating a little state
|
// the write side of a pushed transaction just involves manipulating a little state
|
||||||
SetSentFin(true);
|
SetSentFin(true);
|
||||||
Http2Stream::mRequestHeadersDone = 1;
|
Http2Stream::mAllHeadersSent = 1;
|
||||||
Http2Stream::mOpenGenerated = 1;
|
|
||||||
Http2Stream::ChangeState(UPSTREAM_COMPLETE);
|
Http2Stream::ChangeState(UPSTREAM_COMPLETE);
|
||||||
*count = 0;
|
*count = 0;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -438,15 +438,13 @@ Http2Session::AddStream(nsAHttpTransaction *aHttpTransaction,
|
||||||
|
|
||||||
mStreamTransactionHash.Put(aHttpTransaction, stream);
|
mStreamTransactionHash.Put(aHttpTransaction, stream);
|
||||||
|
|
||||||
mReadyForWrite.Push(stream);
|
if (RoomForMoreConcurrent()) {
|
||||||
SetWriteCallbacks();
|
LOG3(("Http2Session::AddStream %p stream %p activated immediately.",
|
||||||
|
this, stream));
|
||||||
// Kick off the SYN transmit without waiting for the poll loop
|
ActivateStream(stream);
|
||||||
// This won't work for the first stream because there is no segment reader
|
} else {
|
||||||
// yet.
|
LOG3(("Http2Session::AddStream %p stream %p queued.", this, stream));
|
||||||
if (mSegmentReader) {
|
mQueuedStreams.Push(stream);
|
||||||
uint32_t countRead;
|
|
||||||
ReadSegments(nullptr, kDefaultBufferSize, &countRead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE) &&
|
if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE) &&
|
||||||
|
@ -460,14 +458,32 @@ Http2Session::AddStream(nsAHttpTransaction *aHttpTransaction,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Http2Session::QueueStream(Http2Stream *stream)
|
Http2Session::ActivateStream(Http2Stream *stream)
|
||||||
{
|
{
|
||||||
// will be removed via processpending or a shutdown path
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(!stream->CountAsActive());
|
MOZ_ASSERT(!stream->StreamID() || (stream->StreamID() & 1),
|
||||||
|
"Do not activate pushed streams");
|
||||||
|
|
||||||
LOG3(("Http2Session::QueueStream %p stream %p queued.", this, stream));
|
MOZ_ASSERT(!stream->CountAsActive());
|
||||||
mQueuedStreams.Push(stream);
|
stream->SetCountAsActive(true);
|
||||||
|
++mConcurrent;
|
||||||
|
|
||||||
|
if (mConcurrent > mConcurrentHighWater)
|
||||||
|
mConcurrentHighWater = mConcurrent;
|
||||||
|
LOG3(("Http2Session::AddStream %p activating stream %p Currently %d "
|
||||||
|
"streams in session, high water mark is %d",
|
||||||
|
this, stream, mConcurrent, mConcurrentHighWater));
|
||||||
|
|
||||||
|
mReadyForWrite.Push(stream);
|
||||||
|
SetWriteCallbacks();
|
||||||
|
|
||||||
|
// Kick off the headers transmit without waiting for the poll loop
|
||||||
|
// This won't work for stream id=1 because there is no segment reader
|
||||||
|
// yet.
|
||||||
|
if (mSegmentReader) {
|
||||||
|
uint32_t countRead;
|
||||||
|
ReadSegments(nullptr, kDefaultBufferSize, &countRead);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -475,15 +491,13 @@ Http2Session::ProcessPending()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
Http2Stream*stream;
|
while (RoomForMoreConcurrent()) {
|
||||||
while (RoomForMoreConcurrent() &&
|
Http2Stream *stream = static_cast<Http2Stream *>(mQueuedStreams.PopFront());
|
||||||
(stream = static_cast<Http2Stream *>(mQueuedStreams.PopFront()))) {
|
if (!stream)
|
||||||
|
return;
|
||||||
LOG3(("Http2Session::ProcessPending %p stream %p woken from queue.",
|
LOG3(("Http2Session::ProcessPending %p stream %p activated from queue.",
|
||||||
this, stream));
|
this, stream));
|
||||||
MOZ_ASSERT(!stream->CountAsActive());
|
ActivateStream(stream);
|
||||||
mReadyForWrite.Push(stream);
|
|
||||||
SetWriteCallbacks();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,44 +616,6 @@ Http2Session::ResetDownstreamState()
|
||||||
mInputFrameDataStream = nullptr;
|
mInputFrameDataStream = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if activated (and counted against max)
|
|
||||||
// otherwise return false and queue
|
|
||||||
bool
|
|
||||||
Http2Session::TryToActivate(Http2Stream *aStream)
|
|
||||||
{
|
|
||||||
if (!RoomForMoreConcurrent()) {
|
|
||||||
LOG3(("Http2Session::TryToActivate %p stream=%p no room for more concurrent "
|
|
||||||
"streams %d\n", this, aStream));
|
|
||||||
QueueStream(aStream);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
IncrementConcurrent(aStream);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Http2Session::IncrementConcurrent(Http2Stream *stream)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
|
||||||
MOZ_ASSERT(!stream->StreamID() || (stream->StreamID() & 1),
|
|
||||||
"Do not activate pushed streams");
|
|
||||||
|
|
||||||
nsAHttpTransaction *trans = stream->Transaction();
|
|
||||||
if (!trans || !trans->IsNullTransaction() || trans->QuerySpdyConnectTransaction()) {
|
|
||||||
|
|
||||||
MOZ_ASSERT(!stream->CountAsActive());
|
|
||||||
stream->SetCountAsActive(true);
|
|
||||||
++mConcurrent;
|
|
||||||
|
|
||||||
if (mConcurrent > mConcurrentHighWater) {
|
|
||||||
mConcurrentHighWater = mConcurrent;
|
|
||||||
}
|
|
||||||
LOG3(("Http2Session::IncrementCounter %p counting stream %p Currently %d "
|
|
||||||
"streams in session, high water mark is %d\n",
|
|
||||||
this, stream, mConcurrent, mConcurrentHighWater));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// call with data length (i.e. 0 for 0 data bytes - ignore 9 byte header)
|
// call with data length (i.e. 0 for 0 data bytes - ignore 9 byte header)
|
||||||
// dest must have 9 bytes of allocated space
|
// dest must have 9 bytes of allocated space
|
||||||
template<typename charType> void
|
template<typename charType> void
|
||||||
|
@ -680,7 +656,6 @@ Http2Session::CreateFrameHeader(uint8_t *dest, uint16_t frameLength,
|
||||||
void
|
void
|
||||||
Http2Session::MaybeDecrementConcurrent(Http2Stream *aStream)
|
Http2Session::MaybeDecrementConcurrent(Http2Stream *aStream)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
|
||||||
LOG3(("MaybeDecrementConcurrent %p id=0x%X concurrent=%d active=%d\n",
|
LOG3(("MaybeDecrementConcurrent %p id=0x%X concurrent=%d active=%d\n",
|
||||||
this, aStream->StreamID(), mConcurrent, aStream->CountAsActive()));
|
this, aStream->StreamID(), mConcurrent, aStream->CountAsActive()));
|
||||||
|
|
||||||
|
@ -1475,7 +1450,6 @@ Http2Session::RecvSettings(Http2Session *self)
|
||||||
case SETTINGS_TYPE_MAX_CONCURRENT:
|
case SETTINGS_TYPE_MAX_CONCURRENT:
|
||||||
self->mMaxConcurrent = value;
|
self->mMaxConcurrent = value;
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
||||||
self->ProcessPending();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_INITIAL_WINDOW:
|
case SETTINGS_TYPE_INITIAL_WINDOW:
|
||||||
|
|
|
@ -205,8 +205,8 @@ public:
|
||||||
|
|
||||||
uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
|
uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
|
||||||
|
|
||||||
bool TryToActivate(Http2Stream *stream);
|
|
||||||
void ConnectPushedStream(Http2Stream *stream);
|
void ConnectPushedStream(Http2Stream *stream);
|
||||||
|
void MaybeDecrementConcurrent(Http2Stream *stream);
|
||||||
|
|
||||||
nsresult ConfirmTLSProfile();
|
nsresult ConfirmTLSProfile();
|
||||||
static bool ALPNCallback(nsISupports *securityInfo);
|
static bool ALPNCallback(nsISupports *securityInfo);
|
||||||
|
@ -266,6 +266,8 @@ private:
|
||||||
void SetWriteCallbacks();
|
void SetWriteCallbacks();
|
||||||
void RealignOutputQueue();
|
void RealignOutputQueue();
|
||||||
|
|
||||||
|
bool RoomForMoreConcurrent();
|
||||||
|
void ActivateStream(Http2Stream *);
|
||||||
void ProcessPending();
|
void ProcessPending();
|
||||||
nsresult SetInputFrameDataStream(uint32_t);
|
nsresult SetInputFrameDataStream(uint32_t);
|
||||||
void CreatePriorityNode(uint32_t, uint32_t, uint8_t, const char *);
|
void CreatePriorityNode(uint32_t, uint32_t, uint8_t, const char *);
|
||||||
|
@ -276,11 +278,6 @@ private:
|
||||||
void UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes);
|
void UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes);
|
||||||
void UpdateLocalSessionWindow(uint32_t bytes);
|
void UpdateLocalSessionWindow(uint32_t bytes);
|
||||||
|
|
||||||
void MaybeDecrementConcurrent(Http2Stream *stream);
|
|
||||||
bool RoomForMoreConcurrent();
|
|
||||||
void IncrementConcurrent(Http2Stream *stream);
|
|
||||||
void QueueStream(Http2Stream *stream);
|
|
||||||
|
|
||||||
// a wrapper for all calls to the nshttpconnection level segment writer. Used
|
// a wrapper for all calls to the nshttpconnection level segment writer. Used
|
||||||
// to track network I/O for timeout purposes
|
// to track network I/O for timeout purposes
|
||||||
nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
|
nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
|
||||||
|
|
|
@ -46,8 +46,7 @@ Http2Stream::Http2Stream(nsAHttpTransaction *httpTransaction,
|
||||||
, mSession(session)
|
, mSession(session)
|
||||||
, mUpstreamState(GENERATING_HEADERS)
|
, mUpstreamState(GENERATING_HEADERS)
|
||||||
, mState(IDLE)
|
, mState(IDLE)
|
||||||
, mRequestHeadersDone(0)
|
, mAllHeadersSent(0)
|
||||||
, mOpenGenerated(0)
|
|
||||||
, mAllHeadersReceived(0)
|
, mAllHeadersReceived(0)
|
||||||
, mTransaction(httpTransaction)
|
, mTransaction(httpTransaction)
|
||||||
, mSocketTransport(session->SocketTransport())
|
, mSocketTransport(session->SocketTransport())
|
||||||
|
@ -155,7 +154,7 @@ Http2Stream::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
// If not, mark the stream for callback when writing can proceed.
|
// If not, mark the stream for callback when writing can proceed.
|
||||||
if (NS_SUCCEEDED(rv) &&
|
if (NS_SUCCEEDED(rv) &&
|
||||||
mUpstreamState == GENERATING_HEADERS &&
|
mUpstreamState == GENERATING_HEADERS &&
|
||||||
!mRequestHeadersDone)
|
!mAllHeadersSent)
|
||||||
mSession->TransactionHasDataToWrite(this);
|
mSession->TransactionHasDataToWrite(this);
|
||||||
|
|
||||||
// mTxinlineFrameUsed represents any queued un-sent frame. It might
|
// mTxinlineFrameUsed represents any queued un-sent frame. It might
|
||||||
|
@ -304,17 +303,16 @@ Http2Stream::ParseHttpRequestHeaders(const char *buf,
|
||||||
uint32_t *countUsed)
|
uint32_t *countUsed)
|
||||||
{
|
{
|
||||||
// Returns NS_OK even if the headers are incomplete
|
// Returns NS_OK even if the headers are incomplete
|
||||||
// set mRequestHeadersDone flag if they are complete
|
// set mAllHeadersSent flag if they are complete
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(mUpstreamState == GENERATING_HEADERS);
|
MOZ_ASSERT(mUpstreamState == GENERATING_HEADERS);
|
||||||
MOZ_ASSERT(!mRequestHeadersDone);
|
|
||||||
|
|
||||||
LOG3(("Http2Stream::ParseHttpRequestHeaders %p avail=%d state=%x",
|
LOG3(("Http2Stream::ParseHttpRequestHeaders %p avail=%d state=%x",
|
||||||
this, avail, mUpstreamState));
|
this, avail, mUpstreamState));
|
||||||
|
|
||||||
mFlatHttpRequestHeaders.Append(buf, avail);
|
mFlatHttpRequestHeaders.Append(buf, avail);
|
||||||
const nsHttpRequestHead *head = mTransaction->RequestHead();
|
nsHttpRequestHead *head = mTransaction->RequestHead();
|
||||||
|
|
||||||
// We can use the simple double crlf because firefox is the
|
// We can use the simple double crlf because firefox is the
|
||||||
// only client we are parsing
|
// only client we are parsing
|
||||||
|
@ -335,7 +333,7 @@ Http2Stream::ParseHttpRequestHeaders(const char *buf,
|
||||||
uint32_t oldLen = mFlatHttpRequestHeaders.Length();
|
uint32_t oldLen = mFlatHttpRequestHeaders.Length();
|
||||||
mFlatHttpRequestHeaders.SetLength(endHeader + 2);
|
mFlatHttpRequestHeaders.SetLength(endHeader + 2);
|
||||||
*countUsed = avail - (oldLen - endHeader) + 4;
|
*countUsed = avail - (oldLen - endHeader) + 4;
|
||||||
mRequestHeadersDone = 1;
|
mAllHeadersSent = 1;
|
||||||
|
|
||||||
nsAutoCString authorityHeader;
|
nsAutoCString authorityHeader;
|
||||||
nsAutoCString hashkey;
|
nsAutoCString hashkey;
|
||||||
|
@ -390,32 +388,28 @@ Http2Stream::ParseHttpRequestHeaders(const char *buf,
|
||||||
SetSentFin(true);
|
SetSentFin(true);
|
||||||
AdjustPushedPriority();
|
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
|
// There is probably pushed data buffered so trigger a read manually
|
||||||
// as we can't rely on future network events to do it
|
// as we can't rely on future network events to do it
|
||||||
mSession->ConnectPushedStream(this);
|
mSession->ConnectPushedStream(this);
|
||||||
mOpenGenerated = 1;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is really a headers frame, but open is pretty clear from a workflow pov
|
|
||||||
nsresult
|
|
||||||
Http2Stream::GenerateOpen()
|
|
||||||
{
|
|
||||||
// It is now OK to assign a streamID that we are assured will
|
// It is now OK to assign a streamID that we are assured will
|
||||||
// be monotonically increasing amongst new streams on this
|
// be monotonically increasing amongst new streams on this
|
||||||
// session
|
// session
|
||||||
mStreamID = mSession->RegisterStreamID(this);
|
mStreamID = mSession->RegisterStreamID(this);
|
||||||
MOZ_ASSERT(mStreamID & 1, "Http2 Stream Channel ID must be odd");
|
MOZ_ASSERT(mStreamID & 1, "Http2 Stream Channel ID must be odd");
|
||||||
MOZ_ASSERT(!mOpenGenerated);
|
LOG3(("Stream ID 0x%X [session=%p] for URI %s\n",
|
||||||
|
mStreamID, mSession,
|
||||||
mOpenGenerated = 1;
|
nsCString(head->RequestURI()).get()));
|
||||||
|
|
||||||
const nsHttpRequestHead *head = mTransaction->RequestHead();
|
|
||||||
LOG3(("Http2Stream %p Stream ID 0x%X [session=%p] for URI %s\n",
|
|
||||||
this, mStreamID, mSession, nsCString(head->RequestURI()).get()));
|
|
||||||
|
|
||||||
if (mStreamID >= 0x80000000) {
|
if (mStreamID >= 0x80000000) {
|
||||||
// streamID must fit in 31 bits. Evading This is theoretically possible
|
// streamID must fit in 31 bits. Evading This is theoretically possible
|
||||||
|
@ -434,9 +428,6 @@ Http2Stream::GenerateOpen()
|
||||||
// of HTTP/2 headers by writing to mTxInlineFrame{sz}
|
// of HTTP/2 headers by writing to mTxInlineFrame{sz}
|
||||||
|
|
||||||
nsCString compressedData;
|
nsCString compressedData;
|
||||||
nsAutoCString authorityHeader;
|
|
||||||
head->GetHeader(nsHttp::Host, authorityHeader);
|
|
||||||
|
|
||||||
nsDependentCString scheme(head->IsHTTPS() ? "https" : "http");
|
nsDependentCString scheme(head->IsHTTPS() ? "https" : "http");
|
||||||
if (head->IsConnect()) {
|
if (head->IsConnect()) {
|
||||||
MOZ_ASSERT(mTransaction->QuerySpdyConnectTransaction());
|
MOZ_ASSERT(mTransaction->QuerySpdyConnectTransaction());
|
||||||
|
@ -449,7 +440,6 @@ Http2Stream::GenerateOpen()
|
||||||
if (!ci) {
|
if (!ci) {
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
authorityHeader = ci->GetHost();
|
authorityHeader = ci->GetHost();
|
||||||
authorityHeader.Append(':');
|
authorityHeader.Append(':');
|
||||||
authorityHeader.AppendInt(ci->Port());
|
authorityHeader.AppendInt(ci->Port());
|
||||||
|
@ -1210,26 +1200,12 @@ Http2Stream::OnReadSegment(const char *buf,
|
||||||
// the number of those bytes that we consume (i.e. the portion that are
|
// the number of those bytes that we consume (i.e. the portion that are
|
||||||
// header bytes)
|
// header bytes)
|
||||||
|
|
||||||
if (!mRequestHeadersDone) {
|
rv = ParseHttpRequestHeaders(buf, count, countRead);
|
||||||
if (NS_FAILED(rv = ParseHttpRequestHeaders(buf, count, countRead))) {
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
}
|
LOG3(("ParseHttpRequestHeaders %p used %d of %d. complete = %d",
|
||||||
}
|
this, *countRead, count, mAllHeadersSent));
|
||||||
|
if (mAllHeadersSent) {
|
||||||
if (mRequestHeadersDone && !mOpenGenerated) {
|
|
||||||
if (!mSession->TryToActivate(this)) {
|
|
||||||
LOG3(("Http2Stream::OnReadSegment %p cannot activate now. queued.\n", this));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (NS_FAILED(rv = GenerateOpen())) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG3(("ParseHttpRequestHeaders %p used %d of %d. "
|
|
||||||
"requestheadersdone = %d mOpenGenerated = %d\n",
|
|
||||||
this, *countRead, count, mRequestHeadersDone, mOpenGenerated));
|
|
||||||
if (mOpenGenerated) {
|
|
||||||
SetHTTPState(OPEN);
|
SetHTTPState(OPEN);
|
||||||
AdjustInitialWindow();
|
AdjustInitialWindow();
|
||||||
// This version of TransmitFrame cannot block
|
// This version of TransmitFrame cannot block
|
||||||
|
|
|
@ -178,13 +178,10 @@ protected:
|
||||||
// The HTTP/2 state for the stream from section 5.1
|
// The HTTP/2 state for the stream from section 5.1
|
||||||
enum stateType mState;
|
enum stateType mState;
|
||||||
|
|
||||||
// Flag is set when all http request headers have been read ID is not stable
|
// Flag is set when all http request headers have been read and ID is stable
|
||||||
uint32_t mRequestHeadersDone : 1;
|
uint32_t mAllHeadersSent : 1;
|
||||||
|
|
||||||
// Flag is set when ID is stable and concurrency limits are met
|
// Flag is set when all http request headers have been read and ID is stable
|
||||||
uint32_t mOpenGenerated : 1;
|
|
||||||
|
|
||||||
// Flag is set when all http response headers have been read
|
|
||||||
uint32_t mAllHeadersReceived : 1;
|
uint32_t mAllHeadersReceived : 1;
|
||||||
|
|
||||||
void ChangeState(enum upstreamStateType);
|
void ChangeState(enum upstreamStateType);
|
||||||
|
@ -193,8 +190,6 @@ private:
|
||||||
friend class nsAutoPtr<Http2Stream>;
|
friend class nsAutoPtr<Http2Stream>;
|
||||||
|
|
||||||
nsresult ParseHttpRequestHeaders(const char *, uint32_t, uint32_t *);
|
nsresult ParseHttpRequestHeaders(const char *, uint32_t, uint32_t *);
|
||||||
nsresult GenerateOpen();
|
|
||||||
|
|
||||||
void AdjustPushedPriority();
|
void AdjustPushedPriority();
|
||||||
void AdjustInitialWindow();
|
void AdjustInitialWindow();
|
||||||
nsresult TransmitFrame(const char *, uint32_t *, bool forceCommitment);
|
nsresult TransmitFrame(const char *, uint32_t *, bool forceCommitment);
|
||||||
|
|
|
@ -106,8 +106,7 @@ SpdyPushedStream31::ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *co
|
||||||
|
|
||||||
// the write side of a pushed transaction just involves manipulating a little state
|
// the write side of a pushed transaction just involves manipulating a little state
|
||||||
SpdyStream31::mSentFinOnData = 1;
|
SpdyStream31::mSentFinOnData = 1;
|
||||||
SpdyStream31::mRequestHeadersDone = 1;
|
SpdyStream31::mSynFrameComplete = 1;
|
||||||
SpdyStream31::mSynFrameGenerated = 1;
|
|
||||||
SpdyStream31::ChangeState(UPSTREAM_COMPLETE);
|
SpdyStream31::ChangeState(UPSTREAM_COMPLETE);
|
||||||
*count = 0;
|
*count = 0;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -379,15 +379,14 @@ SpdySession31::AddStream(nsAHttpTransaction *aHttpTransaction,
|
||||||
|
|
||||||
mStreamTransactionHash.Put(aHttpTransaction, stream);
|
mStreamTransactionHash.Put(aHttpTransaction, stream);
|
||||||
|
|
||||||
mReadyForWrite.Push(stream);
|
if (RoomForMoreConcurrent()) {
|
||||||
SetWriteCallbacks();
|
LOG3(("SpdySession31::AddStream %p stream %p activated immediately.",
|
||||||
|
this, stream));
|
||||||
// Kick off the SYN transmit without waiting for the poll loop
|
ActivateStream(stream);
|
||||||
// This won't work for stream id=1 because there is no segment reader
|
}
|
||||||
// yet.
|
else {
|
||||||
if (mSegmentReader) {
|
LOG3(("SpdySession31::AddStream %p stream %p queued.", this, stream));
|
||||||
uint32_t countRead;
|
mQueuedStreams.Push(stream);
|
||||||
ReadSegments(nullptr, kDefaultBufferSize, &countRead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE) &&
|
if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE) &&
|
||||||
|
@ -401,14 +400,33 @@ SpdySession31::AddStream(nsAHttpTransaction *aHttpTransaction,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SpdySession31::QueueStream(SpdyStream31 *stream)
|
SpdySession31::ActivateStream(SpdyStream31 *stream)
|
||||||
{
|
{
|
||||||
// will be removed via processpending or a shutdown path
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(!stream->CountAsActive());
|
MOZ_ASSERT(!stream->StreamID() || (stream->StreamID() & 1),
|
||||||
|
"Do not activate pushed streams");
|
||||||
|
|
||||||
LOG3(("SpdySession31::QueueStream %p stream %p queued.", this, stream));
|
nsAHttpTransaction *trans = stream->Transaction();
|
||||||
mQueuedStreams.Push(stream);
|
if (!trans || !trans->IsNullTransaction() || trans->QuerySpdyConnectTransaction()) {
|
||||||
|
++mConcurrent;
|
||||||
|
if (mConcurrent > mConcurrentHighWater) {
|
||||||
|
mConcurrentHighWater = mConcurrent;
|
||||||
|
}
|
||||||
|
LOG3(("SpdySession31::AddStream %p activating stream %p Currently %d "
|
||||||
|
"streams in session, high water mark is %d",
|
||||||
|
this, stream, mConcurrent, mConcurrentHighWater));
|
||||||
|
}
|
||||||
|
|
||||||
|
mReadyForWrite.Push(stream);
|
||||||
|
SetWriteCallbacks();
|
||||||
|
|
||||||
|
// Kick off the SYN transmit without waiting for the poll loop
|
||||||
|
// This won't work for stream id=1 because there is no segment reader
|
||||||
|
// yet.
|
||||||
|
if (mSegmentReader) {
|
||||||
|
uint32_t countRead;
|
||||||
|
ReadSegments(nullptr, kDefaultBufferSize, &countRead);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -416,15 +434,13 @@ SpdySession31::ProcessPending()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
SpdyStream31 *stream;
|
while (RoomForMoreConcurrent()) {
|
||||||
while (RoomForMoreConcurrent() &&
|
SpdyStream31 *stream = static_cast<SpdyStream31 *>(mQueuedStreams.PopFront());
|
||||||
(stream = static_cast<SpdyStream31 *>(mQueuedStreams.PopFront()))) {
|
if (!stream)
|
||||||
|
return;
|
||||||
LOG3(("SpdySession31::ProcessPending %p stream %p woken from queue.",
|
LOG3(("SpdySession31::ProcessPending %p stream %p activated from queue.",
|
||||||
this, stream));
|
this, stream));
|
||||||
MOZ_ASSERT(!stream->CountAsActive());
|
ActivateStream(stream);
|
||||||
mReadyForWrite.Push(stream);
|
|
||||||
SetWriteCallbacks();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,60 +561,18 @@ SpdySession31::ResetDownstreamState()
|
||||||
mInputFrameDataStream = nullptr;
|
mInputFrameDataStream = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if activated (and counted against max)
|
|
||||||
// otherwise return false and queue
|
|
||||||
bool
|
|
||||||
SpdySession31::TryToActivate(SpdyStream31 *aStream)
|
|
||||||
{
|
|
||||||
if (!RoomForMoreConcurrent()) {
|
|
||||||
LOG3(("SpdySession31::TryToActivate %p stream=%p no room for more concurrent "
|
|
||||||
"streams %d\n", this, aStream));
|
|
||||||
QueueStream(aStream);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
IncrementConcurrent(aStream);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SpdySession31::IncrementConcurrent(SpdyStream31 *stream)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
|
||||||
MOZ_ASSERT(!stream->StreamID() || (stream->StreamID() & 1),
|
|
||||||
"Do not activate pushed streams");
|
|
||||||
|
|
||||||
nsAHttpTransaction *trans = stream->Transaction();
|
|
||||||
if (!trans || !trans->IsNullTransaction() || trans->QuerySpdyConnectTransaction()) {
|
|
||||||
|
|
||||||
MOZ_ASSERT(!stream->CountAsActive());
|
|
||||||
stream->SetCountAsActive(true);
|
|
||||||
++mConcurrent;
|
|
||||||
|
|
||||||
if (mConcurrent > mConcurrentHighWater) {
|
|
||||||
mConcurrentHighWater = mConcurrent;
|
|
||||||
}
|
|
||||||
LOG3(("SpdySession31::AddStream %p counting stream %p Currently %d "
|
|
||||||
"streams in session, high water mark is %d",
|
|
||||||
this, stream, mConcurrent, mConcurrentHighWater));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SpdySession31::DecrementConcurrent(SpdyStream31 *aStream)
|
SpdySession31::DecrementConcurrent(SpdyStream31 *aStream)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
uint32_t id = aStream->StreamID();
|
||||||
|
|
||||||
if (!aStream->CountAsActive()) {
|
if (id && !(id & 0x1))
|
||||||
return;
|
return; // pushed streams aren't counted in concurrent limit
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(mConcurrent);
|
MOZ_ASSERT(mConcurrent);
|
||||||
aStream->SetCountAsActive(false);
|
|
||||||
--mConcurrent;
|
--mConcurrent;
|
||||||
|
|
||||||
LOG3(("DecrementConcurrent %p id=0x%X concurrent=%d\n",
|
LOG3(("DecrementConcurrent %p id=0x%X concurrent=%d\n",
|
||||||
this, aStream->StreamID(), mConcurrent));
|
this, id, mConcurrent));
|
||||||
|
|
||||||
ProcessPending();
|
ProcessPending();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1440,7 +1414,6 @@ SpdySession31::HandleSettings(SpdySession31 *self)
|
||||||
case SETTINGS_TYPE_MAX_CONCURRENT:
|
case SETTINGS_TYPE_MAX_CONCURRENT:
|
||||||
self->mMaxConcurrent = value;
|
self->mMaxConcurrent = value;
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
||||||
self->ProcessPending();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_CWND:
|
case SETTINGS_TYPE_CWND:
|
||||||
|
|
|
@ -178,7 +178,6 @@ public:
|
||||||
|
|
||||||
uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
|
uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
|
||||||
|
|
||||||
bool TryToActivate(SpdyStream31 *stream);
|
|
||||||
void ConnectPushedStream(SpdyStream31 *stream);
|
void ConnectPushedStream(SpdyStream31 *stream);
|
||||||
void DecrementConcurrent(SpdyStream31 *stream);
|
void DecrementConcurrent(SpdyStream31 *stream);
|
||||||
|
|
||||||
|
@ -224,6 +223,8 @@ private:
|
||||||
void SetWriteCallbacks();
|
void SetWriteCallbacks();
|
||||||
void RealignOutputQueue();
|
void RealignOutputQueue();
|
||||||
|
|
||||||
|
bool RoomForMoreConcurrent();
|
||||||
|
void ActivateStream(SpdyStream31 *);
|
||||||
void ProcessPending();
|
void ProcessPending();
|
||||||
nsresult SetInputFrameDataStream(uint32_t);
|
nsresult SetInputFrameDataStream(uint32_t);
|
||||||
bool VerifyStream(SpdyStream31 *, uint32_t);
|
bool VerifyStream(SpdyStream31 *, uint32_t);
|
||||||
|
@ -233,10 +234,6 @@ private:
|
||||||
void UpdateLocalStreamWindow(SpdyStream31 *stream, uint32_t bytes);
|
void UpdateLocalStreamWindow(SpdyStream31 *stream, uint32_t bytes);
|
||||||
void UpdateLocalSessionWindow(uint32_t bytes);
|
void UpdateLocalSessionWindow(uint32_t bytes);
|
||||||
|
|
||||||
bool RoomForMoreConcurrent();
|
|
||||||
void IncrementConcurrent(SpdyStream31 *stream);
|
|
||||||
void QueueStream(SpdyStream31 *stream);
|
|
||||||
|
|
||||||
// a wrapper for all calls to the nshttpconnection level segment writer. Used
|
// a wrapper for all calls to the nshttpconnection level segment writer. Used
|
||||||
// to track network I/O for timeout purposes
|
// to track network I/O for timeout purposes
|
||||||
nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
|
nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
|
||||||
|
|
|
@ -42,8 +42,7 @@ SpdyStream31::SpdyStream31(nsAHttpTransaction *httpTransaction,
|
||||||
: mStreamID(0)
|
: mStreamID(0)
|
||||||
, mSession(spdySession)
|
, mSession(spdySession)
|
||||||
, mUpstreamState(GENERATING_SYN_STREAM)
|
, mUpstreamState(GENERATING_SYN_STREAM)
|
||||||
, mRequestHeadersDone(0)
|
, mSynFrameComplete(0)
|
||||||
, mSynFrameGenerated(0)
|
|
||||||
, mSentFinOnData(0)
|
, mSentFinOnData(0)
|
||||||
, mTransaction(httpTransaction)
|
, mTransaction(httpTransaction)
|
||||||
, mSocketTransport(spdySession->SocketTransport())
|
, mSocketTransport(spdySession->SocketTransport())
|
||||||
|
@ -56,7 +55,6 @@ SpdyStream31::SpdyStream31(nsAHttpTransaction *httpTransaction,
|
||||||
, mSentWaitingFor(0)
|
, mSentWaitingFor(0)
|
||||||
, mReceivedData(0)
|
, mReceivedData(0)
|
||||||
, mSetTCPSocketBuffer(0)
|
, mSetTCPSocketBuffer(0)
|
||||||
, mCountAsActive(0)
|
|
||||||
, mTxInlineFrameSize(SpdySession31::kDefaultBufferSize)
|
, mTxInlineFrameSize(SpdySession31::kDefaultBufferSize)
|
||||||
, mTxInlineFrameUsed(0)
|
, mTxInlineFrameUsed(0)
|
||||||
, mTxStreamFrameSize(0)
|
, mTxStreamFrameSize(0)
|
||||||
|
@ -131,7 +129,7 @@ SpdyStream31::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
// If not, mark the stream for callback when writing can proceed.
|
// If not, mark the stream for callback when writing can proceed.
|
||||||
if (NS_SUCCEEDED(rv) &&
|
if (NS_SUCCEEDED(rv) &&
|
||||||
mUpstreamState == GENERATING_SYN_STREAM &&
|
mUpstreamState == GENERATING_SYN_STREAM &&
|
||||||
!mRequestHeadersDone)
|
!mSynFrameComplete)
|
||||||
mSession->TransactionHasDataToWrite(this);
|
mSession->TransactionHasDataToWrite(this);
|
||||||
|
|
||||||
// mTxinlineFrameUsed represents any queued un-sent frame. It might
|
// mTxinlineFrameUsed represents any queued un-sent frame. It might
|
||||||
|
@ -261,11 +259,10 @@ SpdyStream31::ParseHttpRequestHeaders(const char *buf,
|
||||||
uint32_t *countUsed)
|
uint32_t *countUsed)
|
||||||
{
|
{
|
||||||
// Returns NS_OK even if the headers are incomplete
|
// Returns NS_OK even if the headers are incomplete
|
||||||
// set mRequestHeadersDone flag if they are complete
|
// set mSynFrameComplete flag if they are complete
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(mUpstreamState == GENERATING_SYN_STREAM);
|
MOZ_ASSERT(mUpstreamState == GENERATING_SYN_STREAM);
|
||||||
MOZ_ASSERT(!mRequestHeadersDone);
|
|
||||||
|
|
||||||
LOG3(("SpdyStream31::ParseHttpRequestHeaders %p avail=%d state=%x",
|
LOG3(("SpdyStream31::ParseHttpRequestHeaders %p avail=%d state=%x",
|
||||||
this, avail, mUpstreamState));
|
this, avail, mUpstreamState));
|
||||||
|
@ -291,7 +288,7 @@ SpdyStream31::ParseHttpRequestHeaders(const char *buf,
|
||||||
uint32_t oldLen = mFlatHttpRequestHeaders.Length();
|
uint32_t oldLen = mFlatHttpRequestHeaders.Length();
|
||||||
mFlatHttpRequestHeaders.SetLength(endHeader + 2);
|
mFlatHttpRequestHeaders.SetLength(endHeader + 2);
|
||||||
*countUsed = avail - (oldLen - endHeader) + 4;
|
*countUsed = avail - (oldLen - endHeader) + 4;
|
||||||
mRequestHeadersDone = 1;
|
mSynFrameComplete = 1;
|
||||||
|
|
||||||
nsAutoCString hostHeader;
|
nsAutoCString hostHeader;
|
||||||
nsAutoCString hashkey;
|
nsAutoCString hashkey;
|
||||||
|
@ -333,24 +330,15 @@ SpdyStream31::ParseHttpRequestHeaders(const char *buf,
|
||||||
// There is probably pushed data buffered so trigger a read manually
|
// There is probably pushed data buffered so trigger a read manually
|
||||||
// as we can't rely on future network events to do it
|
// as we can't rely on future network events to do it
|
||||||
mSession->ConnectPushedStream(this);
|
mSession->ConnectPushedStream(this);
|
||||||
mSynFrameGenerated = 1;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
SpdyStream31::GenerateSynFrame()
|
|
||||||
{
|
|
||||||
// It is now OK to assign a streamID that we are assured will
|
// It is now OK to assign a streamID that we are assured will
|
||||||
// be monotonically increasing amongst syn-streams on this
|
// be monotonically increasing amongst syn-streams on this
|
||||||
// session
|
// session
|
||||||
mStreamID = mSession->RegisterStreamID(this);
|
mStreamID = mSession->RegisterStreamID(this);
|
||||||
MOZ_ASSERT(mStreamID & 1, "Spdy Stream Channel ID must be odd");
|
MOZ_ASSERT(mStreamID & 1, "Spdy Stream Channel ID must be odd");
|
||||||
MOZ_ASSERT(!mSynFrameGenerated);
|
|
||||||
|
|
||||||
mSynFrameGenerated = 1;
|
|
||||||
|
|
||||||
if (mStreamID >= 0x80000000) {
|
if (mStreamID >= 0x80000000) {
|
||||||
// streamID must fit in 31 bits. This is theoretically possible
|
// streamID must fit in 31 bits. This is theoretically possible
|
||||||
|
@ -519,8 +507,6 @@ SpdyStream31::GenerateSynFrame()
|
||||||
CompressToFrame(NS_LITERAL_CSTRING(":version"));
|
CompressToFrame(NS_LITERAL_CSTRING(":version"));
|
||||||
CompressToFrame(versionHeader);
|
CompressToFrame(versionHeader);
|
||||||
|
|
||||||
nsAutoCString hostHeader;
|
|
||||||
mTransaction->RequestHead()->GetHeader(nsHttp::Host, hostHeader);
|
|
||||||
CompressToFrame(NS_LITERAL_CSTRING(":host"));
|
CompressToFrame(NS_LITERAL_CSTRING(":host"));
|
||||||
CompressToFrame(hostHeader);
|
CompressToFrame(hostHeader);
|
||||||
|
|
||||||
|
@ -1469,26 +1455,12 @@ SpdyStream31::OnReadSegment(const char *buf,
|
||||||
// the number of those bytes that we consume (i.e. the portion that are
|
// the number of those bytes that we consume (i.e. the portion that are
|
||||||
// header bytes)
|
// header bytes)
|
||||||
|
|
||||||
if (!mRequestHeadersDone) {
|
rv = ParseHttpRequestHeaders(buf, count, countRead);
|
||||||
if (NS_FAILED(rv = ParseHttpRequestHeaders(buf, count, countRead))) {
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
}
|
LOG3(("ParseHttpRequestHeaders %p used %d of %d. complete = %d",
|
||||||
}
|
this, *countRead, count, mSynFrameComplete));
|
||||||
|
if (mSynFrameComplete) {
|
||||||
if (mRequestHeadersDone && !mSynFrameGenerated) {
|
|
||||||
if (!mSession->TryToActivate(this)) {
|
|
||||||
LOG3(("SpdyStream31::OnReadSegment %p cannot activate now. queued.\n", this));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (NS_FAILED(rv = GenerateSynFrame())) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG3(("ParseHttpRequestHeaders %p used %d of %d. "
|
|
||||||
"requestheadersdone = %d mSynFrameGenerated = %d\n",
|
|
||||||
this, *countRead, count, mRequestHeadersDone, mSynFrameGenerated));
|
|
||||||
if (mSynFrameGenerated) {
|
|
||||||
AdjustInitialWindow();
|
AdjustInitialWindow();
|
||||||
rv = TransmitFrame(nullptr, nullptr, true);
|
rv = TransmitFrame(nullptr, nullptr, true);
|
||||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||||
|
|
|
@ -55,9 +55,6 @@ public:
|
||||||
void SetRecvdData(bool aStatus) { mReceivedData = aStatus ? 1 : 0; }
|
void SetRecvdData(bool aStatus) { mReceivedData = aStatus ? 1 : 0; }
|
||||||
bool RecvdData() { return mReceivedData; }
|
bool RecvdData() { return mReceivedData; }
|
||||||
|
|
||||||
void SetCountAsActive(bool aStatus) { mCountAsActive = aStatus ? 1 : 0; }
|
|
||||||
bool CountAsActive() { return mCountAsActive; }
|
|
||||||
|
|
||||||
void UpdateTransportSendEvents(uint32_t count);
|
void UpdateTransportSendEvents(uint32_t count);
|
||||||
void UpdateTransportReadEvents(uint32_t count);
|
void UpdateTransportReadEvents(uint32_t count);
|
||||||
|
|
||||||
|
@ -121,11 +118,8 @@ protected:
|
||||||
// sending_request_body for each SPDY chunk in the upload.
|
// sending_request_body for each SPDY chunk in the upload.
|
||||||
enum stateType mUpstreamState;
|
enum stateType mUpstreamState;
|
||||||
|
|
||||||
// Flag is set when all http request headers have been read
|
// Flag is set when all http request headers have been read and ID is stable
|
||||||
uint32_t mRequestHeadersDone : 1;
|
uint32_t mSynFrameComplete : 1;
|
||||||
|
|
||||||
// Flag is set when stream ID is stable
|
|
||||||
uint32_t mSynFrameGenerated : 1;
|
|
||||||
|
|
||||||
// Flag is set when a FIN has been placed on a data or syn packet
|
// Flag is set when a FIN has been placed on a data or syn packet
|
||||||
// (i.e after the client has closed)
|
// (i.e after the client has closed)
|
||||||
|
@ -141,8 +135,6 @@ private:
|
||||||
void *);
|
void *);
|
||||||
|
|
||||||
nsresult ParseHttpRequestHeaders(const char *, uint32_t, uint32_t *);
|
nsresult ParseHttpRequestHeaders(const char *, uint32_t, uint32_t *);
|
||||||
nsresult GenerateSynFrame();
|
|
||||||
|
|
||||||
void AdjustInitialWindow();
|
void AdjustInitialWindow();
|
||||||
nsresult TransmitFrame(const char *, uint32_t *, bool forceCommitment);
|
nsresult TransmitFrame(const char *, uint32_t *, bool forceCommitment);
|
||||||
void GenerateDataFrameHeader(uint32_t, bool);
|
void GenerateDataFrameHeader(uint32_t, bool);
|
||||||
|
@ -193,9 +185,6 @@ private:
|
||||||
// Flag is set after TCP send autotuning has been disabled
|
// Flag is set after TCP send autotuning has been disabled
|
||||||
uint32_t mSetTCPSocketBuffer : 1;
|
uint32_t mSetTCPSocketBuffer : 1;
|
||||||
|
|
||||||
// Flag is set when stream is counted towards MAX_CONCURRENT streams in session
|
|
||||||
uint32_t mCountAsActive : 1;
|
|
||||||
|
|
||||||
// The InlineFrame and associated data is used for composing control
|
// The InlineFrame and associated data is used for composing control
|
||||||
// frames and data frame headers.
|
// frames and data frame headers.
|
||||||
nsAutoArrayPtr<uint8_t> mTxInlineFrame;
|
nsAutoArrayPtr<uint8_t> mTxInlineFrame;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче