зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1353629 - PBlob refactoring - part 12 - nsInputStreamPump should use BufferedStreams, r=smaug
nsInputStreamPump should use the stream as nsIAsyncInputStream if available. In order to do so, we need to wrap a BufferedStream around it. MediaResource cannot use a simple sync nsIInputStream when BlobURL are involved in the content process.
This commit is contained in:
Родитель
ea2f20f908
Коммит
b50ec2b3c0
|
@ -1520,7 +1520,7 @@ MediaResource::Create(MediaResourceCallback* aCallback,
|
|||
|
||||
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(aChannel);
|
||||
RefPtr<MediaResource> resource;
|
||||
if (fc || IsBlobURI(uri)) {
|
||||
if (fc || (IsBlobURI(uri) && XRE_IsParentProcess())) {
|
||||
resource = new FileMediaResource(aCallback, aChannel, uri, *containerType);
|
||||
} else {
|
||||
resource = new ChannelMediaResource(
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "nsIStreamListener.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
|
||||
|
@ -101,18 +102,21 @@ nsInputStreamPump::PeekStream(PeekSegmentFun callback, void* closure)
|
|||
|
||||
NS_ASSERTION(mAsyncStream, "PeekStream called without stream");
|
||||
|
||||
nsresult rv = CreateBufferedStreamIfNeeded();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// See if the pipe is closed by checking the return of Available.
|
||||
uint64_t dummy64;
|
||||
nsresult rv = mAsyncStream->Available(&dummy64);
|
||||
rv = mBufferedStream->Available(&dummy64);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
uint32_t dummy = (uint32_t)std::min(dummy64, (uint64_t)UINT32_MAX);
|
||||
|
||||
PeekData data(callback, closure);
|
||||
return mAsyncStream->ReadSegments(CallPeekFunc,
|
||||
&data,
|
||||
nsIOService::gDefaultSegmentSize,
|
||||
&dummy);
|
||||
return mBufferedStream->ReadSegments(CallPeekFunc,
|
||||
&data,
|
||||
nsIOService::gDefaultSegmentSize,
|
||||
&dummy);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -550,10 +554,13 @@ nsInputStreamPump::OnStateTransfer()
|
|||
if (NS_FAILED(mStatus))
|
||||
return STATE_STOP;
|
||||
|
||||
nsresult rv;
|
||||
nsresult rv = CreateBufferedStreamIfNeeded();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return STATE_STOP;
|
||||
}
|
||||
|
||||
uint64_t avail;
|
||||
rv = mAsyncStream->Available(&avail);
|
||||
rv = mBufferedStream->Available(&avail);
|
||||
LOG((" Available returned [stream=%p rv=%" PRIx32 " avail=%" PRIu64 "]\n", mAsyncStream.get(),
|
||||
static_cast<uint32_t>(rv), avail));
|
||||
|
||||
|
@ -583,7 +590,7 @@ nsInputStreamPump::OnStateTransfer()
|
|||
// in most cases this QI will succeed (mAsyncStream is almost always
|
||||
// a nsPipeInputStream, which implements nsISeekableStream::Tell).
|
||||
int64_t offsetBefore;
|
||||
nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mAsyncStream);
|
||||
nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mBufferedStream);
|
||||
if (seekable && NS_FAILED(seekable->Tell(&offsetBefore))) {
|
||||
NS_NOTREACHED("Tell failed on readable stream");
|
||||
offsetBefore = 0;
|
||||
|
@ -602,7 +609,7 @@ nsInputStreamPump::OnStateTransfer()
|
|||
// nsInputStreamPumps are needed (e.g. nsHttpChannel).
|
||||
mMonitor.Exit();
|
||||
rv = mListener->OnDataAvailable(this, mListenerContext,
|
||||
mAsyncStream, mStreamOffset,
|
||||
mBufferedStream, mStreamOffset,
|
||||
odaAvail);
|
||||
mMonitor.Enter();
|
||||
}
|
||||
|
@ -647,7 +654,7 @@ nsInputStreamPump::OnStateTransfer()
|
|||
// Available may return 0 bytes available at the moment; that
|
||||
// would not mean that we are done.
|
||||
// XXX async streams should have a GetStatus method!
|
||||
rv = mAsyncStream->Available(&avail);
|
||||
rv = mBufferedStream->Available(&avail);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return STATE_TRANSFER;
|
||||
if (rv != NS_BASE_STREAM_CLOSED)
|
||||
|
@ -708,6 +715,7 @@ nsInputStreamPump::OnStateStop()
|
|||
mAsyncStream->Close();
|
||||
|
||||
mAsyncStream = nullptr;
|
||||
mBufferedStream = nullptr;
|
||||
mTargetThread = nullptr;
|
||||
mIsPending = false;
|
||||
{
|
||||
|
@ -727,6 +735,28 @@ nsInputStreamPump::OnStateStop()
|
|||
return STATE_IDLE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsInputStreamPump::CreateBufferedStreamIfNeeded()
|
||||
{
|
||||
if (mBufferedStream) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// ReadSegments is not available for any nsIAsyncInputStream. In order to use
|
||||
// it, we wrap a nsIBufferedInputStream around it, if needed.
|
||||
|
||||
if (NS_InputStreamIsBuffered(mAsyncStream)) {
|
||||
mBufferedStream = mAsyncStream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(mBufferedStream),
|
||||
mAsyncStream, 4096);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIThreadRetargetableRequest
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -75,6 +75,7 @@ protected:
|
|||
uint32_t OnStateStart();
|
||||
uint32_t OnStateTransfer();
|
||||
uint32_t OnStateStop();
|
||||
nsresult CreateBufferedStreamIfNeeded();
|
||||
|
||||
uint32_t mState;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
@ -83,6 +84,7 @@ protected:
|
|||
nsCOMPtr<nsIEventTarget> mTargetThread;
|
||||
nsCOMPtr<nsIInputStream> mStream;
|
||||
nsCOMPtr<nsIAsyncInputStream> mAsyncStream;
|
||||
nsCOMPtr<nsIInputStream> mBufferedStream;
|
||||
uint64_t mStreamOffset;
|
||||
uint64_t mStreamLength;
|
||||
uint32_t mSegSize;
|
||||
|
|
Загрузка…
Ссылка в новой задаче