Bug 1637742 - P2 - IPCBlobInputStream does not return error and executes callback on AsyncWait/AsyncLengthWait if stream is closed r=baku

Depends on D77407

Differential Revision: https://phabricator.services.mozilla.com/D77408
This commit is contained in:
ssengupta 2020-06-02 13:21:16 +00:00
Родитель ccfae4a0f0
Коммит 981a0e4d28
1 изменённых файлов: 60 добавлений и 48 удалений

Просмотреть файл

@ -431,16 +431,26 @@ IPCBlobInputStream::AsyncWait(nsIInputStreamCallback* aCallback,
break; break;
} }
// Stream is closed. case eClosed:
[[fallthrough]];
default: default:
MOZ_ASSERT(mState == eClosed); MOZ_ASSERT(mState == eClosed);
return NS_BASE_STREAM_CLOSED; if (mInputStreamCallback && aCallback) {
return NS_ERROR_FAILURE;
}
break;
} }
} }
MOZ_ASSERT(asyncRemoteStream); if (asyncRemoteStream) {
return asyncRemoteStream->AsyncWait(aCallback ? this : nullptr, 0, 0, return asyncRemoteStream->AsyncWait(aCallback ? this : nullptr, 0, 0,
aEventTarget); aEventTarget);
}
// if asyncRemoteStream is nullptr here, that probably means the stream has
// been closed and the callback can be executed immediately
InputStreamCallbackRunnable::Execute(aCallback, aEventTarget, this);
return NS_OK;
} }
void IPCBlobInputStream::StreamReady( void IPCBlobInputStream::StreamReady(
@ -803,38 +813,6 @@ IPCBlobInputStream::Length(int64_t* aLength) {
return NS_BASE_STREAM_WOULD_BLOCK; return NS_BASE_STREAM_WOULD_BLOCK;
} }
// nsIAsyncInputStreamLength
NS_IMETHODIMP
IPCBlobInputStream::AsyncLengthWait(nsIInputStreamLengthCallback* aCallback,
nsIEventTarget* aEventTarget) {
MutexAutoLock lock(mMutex);
if (mState == eClosed) {
return NS_BASE_STREAM_CLOSED;
}
if (mConsumed) {
return NS_ERROR_NOT_AVAILABLE;
}
// If we have the callback, we must have the event target.
if (NS_WARN_IF(!!aCallback != !!aEventTarget)) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(mActor);
mLengthCallback = aCallback;
mLengthCallbackEventTarget = aEventTarget;
if (aCallback) {
mActor->LengthNeeded(this, aEventTarget);
}
return NS_OK;
}
namespace { namespace {
class InputStreamLengthCallbackRunnable final : public CancelableRunnable { class InputStreamLengthCallbackRunnable final : public CancelableRunnable {
@ -879,6 +857,39 @@ class InputStreamLengthCallbackRunnable final : public CancelableRunnable {
} // namespace } // namespace
// nsIAsyncInputStreamLength
NS_IMETHODIMP
IPCBlobInputStream::AsyncLengthWait(nsIInputStreamLengthCallback* aCallback,
nsIEventTarget* aEventTarget) {
// If we have the callback, we must have the event target.
if (NS_WARN_IF(!!aCallback != !!aEventTarget)) {
return NS_ERROR_FAILURE;
}
{
MutexAutoLock lock(mMutex);
mLengthCallback = aCallback;
mLengthCallbackEventTarget = aEventTarget;
if (mState != eClosed && !mConsumed) {
MOZ_ASSERT(mActor);
if (aCallback) {
mActor->LengthNeeded(this, aEventTarget);
}
return NS_OK;
}
}
// If execution has reached here, it means the stream is either closed or
// consumed, and therefore the callback can be executed immediately
InputStreamLengthCallbackRunnable::Execute(aCallback, aEventTarget, this, -1);
return NS_OK;
}
void IPCBlobInputStream::LengthReady(int64_t aLength) { void IPCBlobInputStream::LengthReady(int64_t aLength) {
nsCOMPtr<nsIInputStreamLengthCallback> lengthCallback; nsCOMPtr<nsIInputStreamLengthCallback> lengthCallback;
nsCOMPtr<nsIEventTarget> lengthCallbackEventTarget; nsCOMPtr<nsIEventTarget> lengthCallbackEventTarget;
@ -886,11 +897,11 @@ void IPCBlobInputStream::LengthReady(int64_t aLength) {
{ {
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
// We have been closed in the meantime. // Stream has been closed in the meantime. Callback can be executed
// immediately
if (mState == eClosed || mConsumed) { if (mState == eClosed || mConsumed) {
return; aLength = -1;
} } else {
if (mStart > 0) { if (mStart > 0) {
aLength -= mStart; aLength -= mStart;
} }
@ -900,6 +911,7 @@ void IPCBlobInputStream::LengthReady(int64_t aLength) {
// value. // value.
aLength = XPCOM_MIN(aLength, (int64_t)mLength); aLength = XPCOM_MIN(aLength, (int64_t)mLength);
} }
}
lengthCallback.swap(mLengthCallback); lengthCallback.swap(mLengthCallback);
lengthCallbackEventTarget.swap(mLengthCallbackEventTarget); lengthCallbackEventTarget.swap(mLengthCallbackEventTarget);