fixes bug 146884 - Mozilla sometimes consumes 100% CPU when pipelining is enabled...

r=dougt sr=rpotts a=asa
This commit is contained in:
darin%netscape.com 2002-07-27 01:06:05 +00:00
parent b7d1e5470a
commit f45557bdd7
3 changed files with 26 additions and 1 deletions

View File

@ -2935,6 +2935,13 @@ nsSocketReadRequest::OnRead()
// Allow reads beyond what is available right now.
amount = MAX_IO_TRANSFER_SIZE;
// Since the input stream remembers any socket errors, we need to
// be sure to clear the error state before calling OnDataAvailable.
// If we don't, and the listener fails to call the Read method on
// mInputStream, then GotWouldBlock() might incorrectly return TRUE,
// which could lead us to loop indefinitely (See bug 146884).
mInputStream->ClearError();
LOG(("nsSocketReadRequest: [this=%x] calling listener [offset=%u, count=%u]\n",
this, offset, amount));
@ -3038,6 +3045,13 @@ nsSocketWriteRequest::OnWrite()
nsresult rv;
PRUint32 offset = mOutputStream->GetOffset();
// Since the output stream remembers any socket errors, we need to
// be sure to clear the error state before calling OnDataWritable.
// If we don't, and the provider fails to call the Write method on
// mOutputStream, then GotWouldBlock() might incorrectly return TRUE,
// which could lead us to loop indefinitely (See bug 146884).
mOutputStream->ClearError();
rv = mProvider->OnDataWritable(this,
mContext,
mOutputStream,

View File

@ -386,6 +386,7 @@ public:
PRBool GotWouldBlock() { return mError == PR_WOULD_BLOCK_ERROR; }
PRBool GotError() { return mError != 0; }
PRErrorCode GetError() { return mError; }
void ClearError() { mError = 0; }
private:
PRUint32 mOffset;
@ -413,6 +414,7 @@ public:
PRBool GotWouldBlock() { return mError == PR_WOULD_BLOCK_ERROR; }
PRBool GotError() { return mError != 0; }
PRErrorCode GetError() { return mError; }
void ClearError() { mError = 0; }
private:
static NS_METHOD WriteFromSegments(nsIInputStream *, void *, const char *,

View File

@ -439,13 +439,22 @@ nsHttpPipeline::OnDataWritable(nsIOutputStream *stream)
// maybe this transaction has already been canceled...
if (mTransactionQ[i]) {
while (1) {
PRUint32 before = 0, after = 0;
mRequestData->Available(&before);
// append the transaction's request data to our buffer...
rv = mTransactionQ[i]->OnDataWritable(outputStream);
if (rv == NS_BASE_STREAM_CLOSED)
break; // advance to next transaction
if (NS_FAILED(rv))
return rv; // something bad happened!!
// else, there's more to write (the transaction may be
// writing in small chunks).
// writing in small chunks). verify that the transaction
// actually wrote something to the pipe, and if it didn't,
// then advance to the next transaction to avoid an
// infinite loop (see bug 146884).
mRequestData->Available(&after);
if (before == after)
break;
}
}
}