зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
ccfae4a0f0
Коммит
981a0e4d28
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче