зеркало из 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;
|
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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче