Bug 1357244. P2 - enforce the invariant that a block is in mFreeBlocks iff it has no owners. r=gerald

http://searchfox.org/mozilla-central/rev/4bd7a206dea5382c97a8a0c30beef668cc449f5b/dom/media/MediaCache.cpp#1529
Note we might return here with mOwners is empty and break the invariant.

MozReview-Commit-ID: JC5OtEU0B8O

--HG--
extra : rebase_source : f842601db12e047fd73a9b062612da2f2b7c0263
This commit is contained in:
JW Wang 2017-04-18 10:44:38 +08:00
Родитель e82ac126f4
Коммит 57f154251e
1 изменённых файлов: 22 добавлений и 14 удалений

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

@ -1519,36 +1519,44 @@ MediaCache::AllocateAndWriteBlock(
LOG("Allocated block %d to stream %p block %d(%" PRId64 ")",
blockIndex, aStream, streamBlockIndex, streamBlockIndex*BLOCK_SIZE);
mFreeBlocks.RemoveBlock(blockIndex);
// Tell each stream using this resource about the new block.
ResourceStreamIterator iter(aStream->mResourceID);
while (MediaCacheStream* stream = iter.Next()) {
BlockOwner* bo = block->mOwners.AppendElement();
if (!bo)
if (!bo) {
// Roll back mOwners if any allocation fails.
block->mOwners.Clear();
return;
}
bo->mStream = stream;
bo->mStreamBlock = streamBlockIndex;
bo->mLastUseTime = now;
stream->mBlocks[streamBlockIndex] = blockIndex;
if (streamBlockIndex*BLOCK_SIZE < stream->mStreamOffset) {
bo->mClass = aMode == MediaCacheStream::MODE_PLAYBACK ? PLAYED_BLOCK
: METADATA_BLOCK;
}
// Tell each stream using this resource about the new block.
for (auto& bo : block->mOwners) {
bo.mStreamBlock = streamBlockIndex;
bo.mLastUseTime = now;
bo.mStream->mBlocks[streamBlockIndex] = blockIndex;
if (streamBlockIndex*BLOCK_SIZE < bo.mStream->mStreamOffset) {
bo.mClass = aMode == MediaCacheStream::MODE_PLAYBACK ? PLAYED_BLOCK
: METADATA_BLOCK;
// This must be the most-recently-used block, since we
// marked it as used now (which may be slightly bogus, but we'll
// treat it as used for simplicity).
GetListForBlock(bo)->AddFirstBlock(blockIndex);
GetListForBlock(&bo)->AddFirstBlock(blockIndex);
Verify();
} else {
// This may not be the latest readahead block, although it usually
// will be. We may have to scan for the right place to insert
// the block in the list.
bo->mClass = READAHEAD_BLOCK;
InsertReadaheadBlock(bo, blockIndex);
bo.mClass = READAHEAD_BLOCK;
InsertReadaheadBlock(&bo, blockIndex);
}
}
// Invariant: block->mOwners.IsEmpty() iff we can find an entry
// in mFreeBlocks for a given blockIndex.
MOZ_DIAGNOSTIC_ASSERT(!block->mOwners.IsEmpty());
mFreeBlocks.RemoveBlock(blockIndex);
nsresult rv = mFileCache->WriteBlock(blockIndex, aData1, aData2);
if (NS_FAILED(rv)) {
LOG("Released block %d from stream %p block %d(%" PRId64 ")",