зеркало из https://github.com/mozilla/gecko-dev.git
Fix to not call OnStartRequest if channel has been canceled. Bug #31957
This commit is contained in:
Родитель
546ab964f8
Коммит
f1f675ff42
|
@ -95,7 +95,18 @@ void PR_CALLBACK nsStreamListenerEvent::HandlePLEvent(PLEvent* aEvent)
|
||||||
NS_ASSERTION(nsnull != ev,"null event.");
|
NS_ASSERTION(nsnull != ev,"null event.");
|
||||||
|
|
||||||
nsresult rv = ev->HandleEvent();
|
nsresult rv = ev->HandleEvent();
|
||||||
ev->mListener->SetStatus(rv);
|
//
|
||||||
|
// If the consumer fails, then cancel the transport. This is necessary
|
||||||
|
// in case where the socket transport is blocked waiting for room in the
|
||||||
|
// pipe, but the consumer fails without consuming all the data.
|
||||||
|
//
|
||||||
|
// Unless the transport is cancelled, it will block forever, waiting for
|
||||||
|
// the pipe to empty...
|
||||||
|
//
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
nsresult cancelRv = ev->mChannel->Cancel(rv);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(cancelRv), "Cancel failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PR_CALLBACK nsStreamListenerEvent::DestroyPLEvent(PLEvent* aEvent)
|
void PR_CALLBACK nsStreamListenerEvent::DestroyPLEvent(PLEvent* aEvent)
|
||||||
|
@ -193,15 +204,23 @@ nsOnStartRequestEvent::HandleEvent()
|
||||||
("netlibEvent: Handle Start [event=%x]", this));
|
("netlibEvent: Handle Start [event=%x]", this));
|
||||||
#endif
|
#endif
|
||||||
nsIStreamObserver* receiver = (nsIStreamObserver*)mListener->GetReceiver();
|
nsIStreamObserver* receiver = (nsIStreamObserver*)mListener->GetReceiver();
|
||||||
return receiver->OnStartRequest(mChannel, mContext);
|
nsresult status;
|
||||||
|
nsresult rv = mChannel->GetStatus(&status);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
|
||||||
|
rv = receiver->OnStartRequest(mChannel, mContext);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NS_WARNING("not calling OnStartRequest");
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsAsyncStreamObserver::OnStartRequest(nsIChannel* channel, nsISupports* context)
|
nsAsyncStreamObserver::OnStartRequest(nsIChannel* channel, nsISupports* context)
|
||||||
{
|
{
|
||||||
nsresult rv = GetStatus();
|
nsresult rv;
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
nsOnStartRequestEvent* event =
|
nsOnStartRequestEvent* event =
|
||||||
new nsOnStartRequestEvent(this, channel, context);
|
new nsOnStartRequestEvent(this, channel, context);
|
||||||
if (event == nsnull)
|
if (event == nsnull)
|
||||||
|
@ -273,14 +292,16 @@ nsOnStopRequestEvent::HandleEvent()
|
||||||
("netlibEvent: Handle Stop [event=%x]", this));
|
("netlibEvent: Handle Stop [event=%x]", this));
|
||||||
#endif
|
#endif
|
||||||
nsIStreamObserver* receiver = (nsIStreamObserver*)mListener->GetReceiver();
|
nsIStreamObserver* receiver = (nsIStreamObserver*)mListener->GetReceiver();
|
||||||
nsresult rv = mListener->GetStatus();
|
nsresult status = NS_OK;
|
||||||
|
nsresult rv = mChannel->GetStatus(&status);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the consumer returned a failure code, then pass it out in the
|
// If the consumer returned a failure code, then pass it out in the
|
||||||
// OnStopRequest(...) notification...
|
// OnStopRequest(...) notification...
|
||||||
//
|
//
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_SUCCEEDED(rv) && NS_FAILED(status)) {
|
||||||
mStatus = rv;
|
mStatus = status;
|
||||||
}
|
}
|
||||||
return receiver->OnStopRequest(mChannel, mContext, mStatus, mMessage);
|
return receiver->OnStopRequest(mChannel, mContext, mStatus, mMessage);
|
||||||
}
|
}
|
||||||
|
@ -372,25 +393,20 @@ nsOnDataAvailableEvent::HandleEvent()
|
||||||
("netlibEvent: Handle Data [event=%x]", this));
|
("netlibEvent: Handle Data [event=%x]", this));
|
||||||
#endif
|
#endif
|
||||||
nsIStreamListener* receiver = (nsIStreamListener*)mListener->GetReceiver();
|
nsIStreamListener* receiver = (nsIStreamListener*)mListener->GetReceiver();
|
||||||
nsresult rv = mListener->GetStatus();
|
nsresult status;
|
||||||
|
nsresult rv = mChannel->GetStatus(&status);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Only send OnDataAvailable(... ) notifications if all previous calls
|
// Only send OnDataAvailable(... ) notifications if all previous calls
|
||||||
// have succeeded...
|
// have succeeded...
|
||||||
//
|
//
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
|
||||||
rv = receiver->OnDataAvailable(mChannel, mContext,
|
rv = receiver->OnDataAvailable(mChannel, mContext,
|
||||||
mIStream, mSourceOffset, mLength);
|
mIStream, mSourceOffset, mLength);
|
||||||
//
|
}
|
||||||
// If the consumer fails, then cancel the transport. This is necessary
|
else {
|
||||||
// in case where the socket transport is blocked waiting for room in the
|
NS_WARNING("not calling OnDataAvailable");
|
||||||
// pipe, but the consumer fails without consuming all the data.
|
|
||||||
//
|
|
||||||
// Unless the transport is cancelled, it will block forever, waiting for
|
|
||||||
// the pipe to empty...
|
|
||||||
//
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
mChannel->Cancel(rv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -401,9 +417,7 @@ nsAsyncStreamListener::OnDataAvailable(nsIChannel* channel, nsISupports* context
|
||||||
PRUint32 aSourceOffset,
|
PRUint32 aSourceOffset,
|
||||||
PRUint32 aLength)
|
PRUint32 aLength)
|
||||||
{
|
{
|
||||||
nsresult rv = GetStatus();
|
nsresult rv;
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
nsOnDataAvailableEvent* event =
|
nsOnDataAvailableEvent* event =
|
||||||
new nsOnDataAvailableEvent(this, channel, context);
|
new nsOnDataAvailableEvent(this, channel, context);
|
||||||
if (event == nsnull)
|
if (event == nsnull)
|
||||||
|
|
|
@ -40,7 +40,6 @@ public:
|
||||||
|
|
||||||
// nsAsyncStreamObserver methods:
|
// nsAsyncStreamObserver methods:
|
||||||
nsAsyncStreamObserver()
|
nsAsyncStreamObserver()
|
||||||
: mStatus(NS_OK)
|
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
}
|
}
|
||||||
|
@ -51,13 +50,10 @@ public:
|
||||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||||
|
|
||||||
nsISupports* GetReceiver() { return mReceiver.get(); }
|
nsISupports* GetReceiver() { return mReceiver.get(); }
|
||||||
nsresult GetStatus() { return mStatus; }
|
|
||||||
void SetStatus(nsresult value) { if (NS_SUCCEEDED(mStatus)) mStatus = value; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsIEventQueue> mEventQueue;
|
nsCOMPtr<nsIEventQueue> mEventQueue;
|
||||||
nsCOMPtr<nsIStreamObserver> mReceiver;
|
nsCOMPtr<nsIStreamObserver> mReceiver;
|
||||||
nsresult mStatus;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1367,8 +1367,13 @@ nsSocketTransport::IsPending(PRBool *result)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSocketTransport::GetStatus(nsresult *status)
|
nsSocketTransport::GetStatus(nsresult *status)
|
||||||
{
|
{
|
||||||
|
if (NS_FAILED(mCancelStatus))
|
||||||
|
*status = mCancelStatus;
|
||||||
|
else if (mStatus == NS_BASE_STREAM_WOULD_BLOCK)
|
||||||
|
*status = NS_OK;
|
||||||
|
else
|
||||||
*status = mStatus;
|
*status = mStatus;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
Загрузка…
Ссылка в новой задаче