Bug 1646933 - DelayedStartInputStream::AsyncWait is wrongly implemented, r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D80342
This commit is contained in:
Andrea Marchesini 2020-06-21 20:53:54 +00:00
parent c8d948863f
commit 7e08e07666

View File

@ -27,6 +27,7 @@ namespace ipc {
class IPCStreamDestination::DelayedStartInputStream final
: public nsIAsyncInputStream,
public nsIInputStreamCallback,
public nsISearchableInputStream,
public nsICloneableInputStream,
public nsIBufferedInputStream {
@ -91,8 +92,19 @@ class IPCStreamDestination::DelayedStartInputStream final
NS_IMETHOD
AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags,
uint32_t aRequestedCount, nsIEventTarget* aTarget) override {
MaybeStartReading();
return mStream->AsyncWait(aCallback, aFlags, aRequestedCount, aTarget);
{
MutexAutoLock lock(mMutex);
if (mAsyncWaitCallback && aCallback) {
return NS_ERROR_FAILURE;
}
mAsyncWaitCallback = aCallback;
MaybeStartReading(lock);
}
nsCOMPtr<nsIInputStreamCallback> callback = aCallback ? this : nullptr;
return mStream->AsyncWait(callback, aFlags, aRequestedCount, aTarget);
}
NS_IMETHOD
@ -138,7 +150,29 @@ class IPCStreamDestination::DelayedStartInputStream final
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsIInputStreamCallback
NS_IMETHOD
OnInputStreamReady(nsIAsyncInputStream* aStream) override {
nsCOMPtr<nsIInputStreamCallback> callback;
{
MutexAutoLock lock(mMutex);
// We have been canceled in the meanwhile.
if (!mAsyncWaitCallback) {
return NS_OK;
}
callback.swap(mAsyncWaitCallback);
}
callback->OnInputStreamReady(this);
return NS_OK;
}
void MaybeStartReading();
void MaybeStartReading(const MutexAutoLock& aProofOfLook);
void MaybeCloseDestination();
@ -148,6 +182,8 @@ class IPCStreamDestination::DelayedStartInputStream final
IPCStreamDestination* mDestination;
nsCOMPtr<nsIAsyncInputStream> mStream;
nsCOMPtr<nsIInputStreamCallback> mAsyncWaitCallback;
// This protects mDestination: any method can be called by any thread.
Mutex mMutex;
@ -195,6 +231,11 @@ class IPCStreamDestination::DelayedStartInputStream::HelperRunnable final
void IPCStreamDestination::DelayedStartInputStream::MaybeStartReading() {
MutexAutoLock lock(mMutex);
MaybeStartReading(lock);
}
void IPCStreamDestination::DelayedStartInputStream::MaybeStartReading(
const MutexAutoLock& aProofOfLook) {
if (!mDestination) {
return;
}
@ -232,6 +273,7 @@ NS_IMPL_RELEASE(IPCStreamDestination::DelayedStartInputStream);
NS_INTERFACE_MAP_BEGIN(IPCStreamDestination::DelayedStartInputStream)
NS_INTERFACE_MAP_ENTRY(nsIAsyncInputStream)
NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
NS_INTERFACE_MAP_ENTRY(nsISearchableInputStream)
NS_INTERFACE_MAP_ENTRY(nsICloneableInputStream)
NS_INTERFACE_MAP_ENTRY(nsIBufferedInputStream)