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;
}
// Stream is closed.
case eClosed:
[[fallthrough]];
default:
MOZ_ASSERT(mState == eClosed);
return NS_BASE_STREAM_CLOSED;
if (mInputStreamCallback && aCallback) {
return NS_ERROR_FAILURE;
}
break;
}
}
MOZ_ASSERT(asyncRemoteStream);
return asyncRemoteStream->AsyncWait(aCallback ? this : nullptr, 0, 0,
aEventTarget);
if (asyncRemoteStream) {
return asyncRemoteStream->AsyncWait(aCallback ? this : nullptr, 0, 0,
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(
@ -803,38 +813,6 @@ IPCBlobInputStream::Length(int64_t* aLength) {
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 {
class InputStreamLengthCallbackRunnable final : public CancelableRunnable {
@ -879,6 +857,39 @@ class InputStreamLengthCallbackRunnable final : public CancelableRunnable {
} // 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) {
nsCOMPtr<nsIInputStreamLengthCallback> lengthCallback;
nsCOMPtr<nsIEventTarget> lengthCallbackEventTarget;
@ -886,19 +897,20 @@ void IPCBlobInputStream::LengthReady(int64_t aLength) {
{
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) {
return;
}
aLength = -1;
} else {
if (mStart > 0) {
aLength -= mStart;
}
if (mStart > 0) {
aLength -= mStart;
}
if (mLength < mActor->Size()) {
// If the remote stream must be sliced, we must return here the correct
// value.
aLength = XPCOM_MIN(aLength, (int64_t)mLength);
if (mLength < mActor->Size()) {
// If the remote stream must be sliced, we must return here the correct
// value.
aLength = XPCOM_MIN(aLength, (int64_t)mLength);
}
}
lengthCallback.swap(mLengthCallback);