Bug 1426578. P4 - offload InitAsClone() to another thread.
MozReview-Commit-ID: H8bQRmkJ8jU
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -1799,18 +1799,16 @@ MediaCache::AllocateAndWriteBlock(AutoLo
QueueUpdate(aLock);
}
void
MediaCache::OpenStream(AutoLock& aLock,
MediaCacheStream* aStream,
bool aIsClone)
{
- NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
-
LOG("Stream %p opened", aStream);
mStreams.AppendElement(aStream);
// A cloned stream should've got the ID from its original.
if (!aIsClone) {
MOZ_ASSERT(aStream->mResourceID == 0, "mResourceID has been initialized.");
aStream->mResourceID = AllocateResourceID(aLock);
}
@@ -2885,16 +2883,29 @@ MediaCacheStream::InitAsClone(MediaCache
mMediaCache = aOriginal->mMediaCache;
// This needs to be done before OpenStream() to avoid data race.
mClientSuspended = true;
// Cloned streams are initially suspended, since there is no channel open
// initially for a clone.
mCacheSuspended = true;
mChannelEnded = true;
+ OwnerThread()->Dispatch(
+ NS_NewRunnableFunction("MediaCacheStream::InitAsClone", [
+ this,
+ aOriginal,
+ r1 = RefPtr<ChannelMediaResource>(mClient),
+ r2 = RefPtr<ChannelMediaResource>(aOriginal->mClient)
+ ]() { InitAsCloneInternal(aOriginal); }));
+}
+
+void
+MediaCacheStream::InitAsCloneInternal(MediaCacheStream* aOriginal)
+{
+ MOZ_ASSERT(OwnerThread()->IsOnCurrentThread());
AutoLock lock(aOriginal->mMediaCache->Monitor());
mResourceID = aOriginal->mResourceID;
// Grab cache blocks from aOriginal as readahead blocks for our stream
mStreamLength = aOriginal->mStreamLength;
mIsTransportSeekable = aOriginal->mIsTransportSeekable;
mDownloadStatistics = aOriginal->mDownloadStatistics;
@@ -2922,16 +2933,19 @@ MediaCacheStream::InitAsClone(MediaCache
// Copy the partial block.
mChannelOffset = aOriginal->mChannelOffset;
memcpy(mPartialBlockBuffer.get(),
aOriginal->mPartialBlockBuffer.get(),
BLOCK_SIZE);
mMediaCache->OpenStream(lock, this, true /* aIsClone */);
+
+ // Wake up the reader which is waiting for the cloned data.
+ lock.NotifyAll();
}
nsIEventTarget*
MediaCacheStream::OwnerThread() const
{
return mMediaCache->OwnerThread();
}
--- a/dom/media/MediaCache.h
+++ b/dom/media/MediaCache.h
@@ -461,16 +461,17 @@ private:
void NotifyDataEndedInternal(uint32_t aLoadID,
nsresult aStatus,
bool aReopenOnError);
void UpdateDownloadStatistics(AutoLock&);
void CloseInternal(AutoLock&);
+ void InitAsCloneInternal(MediaCacheStream* aOriginal);
// Instance of MediaCache to use with this MediaCacheStream.
RefPtr<MediaCache> mMediaCache;
ChannelMediaResource* const mClient;
// The following fields must be written holding the cache's monitor and
// only on the main thread, thus can be read either on the main thread