Bug 1426578. P3 - make MediaCacheStream::InitAsClone() infallible. r=bechen,gerald

It must be infallible for there is no way to propagate the error back to the
main thread when part of the init functions run on another thread. It is OK to
clone a stream that ends abnormally as long as we don't copy the error status
of EOS. The cloned stream will open a new channel when necessary.

Note we also copy the partial block from the original stream to get as much
data as possible and thus reducing the chance of reopening the channel.

MozReview-Commit-ID: 37iYQonFdBU

--HG--
extra : rebase_source : 6bb9983bc8d1f2675557a14acf1824dba4a98fff
extra : intermediate-source : a20ff9a873db93c85750bb2af5bf05c27c9da3c3
extra : source : 0763fb0e7b4ed1096e406dadccb3ca698f39b207
This commit is contained in:
JW Wang 2017-12-16 23:50:07 +08:00
Родитель 1aec590c73
Коммит e43ca27ba0
3 изменённых файлов: 11 добавлений и 16 удалений

Просмотреть файл

@ -580,11 +580,7 @@ ChannelMediaResource::CloneData(MediaResourceCallback* aCallback)
// which will recreate the channel. This way, if all of the media data
// is already in the cache we don't create an unnecessary HTTP channel
// and perform a useless HTTP transaction.
nsresult rv = resource->mCacheStream.InitAsClone(&mCacheStream);
if (NS_FAILED(rv)) {
resource->Close();
return nullptr;
}
resource->mCacheStream.InitAsClone(&mCacheStream);
return resource.forget();
}

Просмотреть файл

@ -2875,7 +2875,7 @@ MediaCacheStream::Init(int64_t aContentLength)
return NS_OK;
}
nsresult
void
MediaCacheStream::InitAsClone(MediaCacheStream* aOriginal)
{
MOZ_ASSERT(!mMediaCache, "Has been initialized.");
@ -2892,12 +2892,6 @@ MediaCacheStream::InitAsClone(MediaCacheStream* aOriginal)
AutoLock lock(aOriginal->mMediaCache->Monitor());
if (aOriginal->mDidNotifyDataEnded &&
NS_FAILED(aOriginal->mNotifyDataEndedStatus)) {
// Streams that ended abnormally are ineligible for cloning.
return NS_ERROR_FAILURE;
}
mResourceID = aOriginal->mResourceID;
// Grab cache blocks from aOriginal as readahead blocks for our stream
@ -2906,7 +2900,8 @@ MediaCacheStream::InitAsClone(MediaCacheStream* aOriginal)
mDownloadStatistics = aOriginal->mDownloadStatistics;
mDownloadStatistics.Stop();
if (aOriginal->mDidNotifyDataEnded) {
if (aOriginal->mDidNotifyDataEnded &&
NS_SUCCEEDED(aOriginal->mNotifyDataEndedStatus)) {
mNotifyDataEndedStatus = aOriginal->mNotifyDataEndedStatus;
mDidNotifyDataEnded = true;
mClient->CacheClientNotifyDataEnded(mNotifyDataEndedStatus);
@ -2925,9 +2920,13 @@ MediaCacheStream::InitAsClone(MediaCacheStream* aOriginal)
mMediaCache->AddBlockOwnerAsReadahead(lock, cacheBlockIndex, this, i);
}
mMediaCache->OpenStream(lock, this, true /* aIsClone */);
// Copy the partial block.
mChannelOffset = aOriginal->mChannelOffset;
memcpy(mPartialBlockBuffer.get(),
aOriginal->mPartialBlockBuffer.get(),
BLOCK_SIZE);
return NS_OK;
mMediaCache->OpenStream(lock, this, true /* aIsClone */);
}
nsIEventTarget*

Просмотреть файл

@ -218,7 +218,7 @@ public:
// as the aOriginal stream.
// Exactly one of InitAsClone or Init must be called before any other method
// on this class.
nsresult InitAsClone(MediaCacheStream* aOriginal);
void InitAsClone(MediaCacheStream* aOriginal);
nsIEventTarget* OwnerThread() const;