Bug 1371882 - MediaBlockCacheBase::Init may be called again to re-initialize cache - r?cpearce
This will be useful to let the MediaCache flush its block cache without having
to restart from scratch (and risk failing).
MozReview-Commit-ID: At3mxH9jb9m
--- a/dom/media/FileBlockCache.cpp
+++ b/dom/media/FileBlockCache.cpp
@@ -68,19 +68,28 @@ FileBlockCache::SetCacheFile(PRFileDesc*
CloseFD(mFD);
mFD = nullptr;
}
}
nsresult
FileBlockCache::Init()
{
+ MutexAutoLock mon(mDataMutex);
+ if (mThread) {
+ LOG("Init() again");
+ // Just discard pending changes, assume MediaCache won't read from
+ // blocks it hasn't written to.
+ mChangeIndexList.clear();
+ mBlockChanges.Clear();
+ return NS_OK;
+ }
+
LOG("Init()");
- MutexAutoLock mon(mDataMutex);
nsresult rv = NS_NewNamedThread("FileBlockCache",
getter_AddRefs(mThread),
nullptr,
SharedThreadPool::kStackSize);
if (NS_FAILED(rv)) {
return rv;
}
@@ -299,17 +308,16 @@ nsresult FileBlockCache::MoveBlockInFile
return WriteBlockToFile(aDestBlockIndex, buf);
}
void
FileBlockCache::PerformBlockIOs()
{
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
MutexAutoLock mon(mDataMutex);
- NS_ASSERTION(!mChangeIndexList.empty(), "Only dispatch when there's work to do");
NS_ASSERTION(mIsWriteScheduled, "Should report write running or scheduled.");
LOG("Run() mFD=%p mThread=%p", mFD, mThread.get());
while (!mChangeIndexList.empty()) {
if (!mThread) {
// We've been closed, abort, discarding unwritten changes.
mIsWriteScheduled = false;
--- a/dom/media/FileBlockCache.h
+++ b/dom/media/FileBlockCache.h
@@ -56,16 +56,18 @@ class FileBlockCache : public MediaBlock
{
public:
FileBlockCache();
protected:
virtual ~FileBlockCache();
public:
+ // Launch thread and open temporary file.
+ // If re-initializing, just discard pending writes if any.
nsresult Init() override;
// Can be called on any thread. This defers to a non-main thread.
nsresult WriteBlock(uint32_t aBlockIndex,
Span<const uint8_t> aData1,
Span<const uint8_t> aData2) override;
// Synchronously reads data from file. May read from file or memory
--- a/dom/media/MediaBlockCacheBase.h
+++ b/dom/media/MediaBlockCacheBase.h
@@ -43,16 +43,18 @@ public:
static_cast<decltype(MediaCacheStream::BLOCK_SIZE)>(INT32_MAX),
"MediaCacheStream::BLOCK_SIZE should fit in 31 bits");
static const int32_t BLOCK_SIZE = MediaCacheStream::BLOCK_SIZE;
protected:
virtual ~MediaBlockCacheBase() {}
public:
+ // Initialize this cache.
+ // If called again, re-initialize cache with minimal chance of failure.
virtual nsresult Init() = 0;
// Can be called on any thread. This defers to a non-main thread.
virtual nsresult WriteBlock(uint32_t aBlockIndex,
Span<const uint8_t> aData1,
Span<const uint8_t> aData2) = 0;
// Synchronously reads data from file. May read from file or memory
--- a/dom/media/MemoryBlockCache.cpp
+++ b/dom/media/MemoryBlockCache.cpp
@@ -66,24 +66,31 @@ MemoryBlockCache::EnsureBufferCanContain
}
mHasGrown = false;
return true;
}
nsresult
MemoryBlockCache::Init()
{
- LOG("@%p Init()", this);
MutexAutoLock lock(mMutex);
- // Attempt to pre-allocate buffer for expected content length.
- if (!EnsureBufferCanContain(mInitialContentLength)) {
- LOG("@%p Init() MEMORYBLOCKCACHE_ERRORS='InitAllocation'", this);
- Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
- InitAllocation);
- return NS_ERROR_FAILURE;
+ if (mBuffer.IsEmpty()) {
+ LOG("@%p Init()", this);
+ // Attempt to pre-allocate buffer for expected content length.
+ if (!EnsureBufferCanContain(mInitialContentLength)) {
+ LOG("@%p Init() MEMORYBLOCKCACHE_ERRORS='InitAllocation'", this);
+ Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
+ InitAllocation);
+ return NS_ERROR_FAILURE;
+ }
+ } else {
+ LOG("@%p Init() again", this);
+ // Re-initialization - Just erase data.
+ MOZ_ASSERT(mBuffer.Length() >= mInitialContentLength);
+ memset(mBuffer.Elements(), 0, mBuffer.Length());
}
// Ignore initial growth.
mHasGrown = false;
return NS_OK;
}
nsresult
MemoryBlockCache::WriteBlock(uint32_t aBlockIndex,
--- a/dom/media/MemoryBlockCache.h
+++ b/dom/media/MemoryBlockCache.h
@@ -34,16 +34,17 @@ class MemoryBlockCache : public MediaBlo
public:
explicit MemoryBlockCache(int64_t aContentLength);
protected:
virtual ~MemoryBlockCache();
public:
// Allocate initial buffer.
+ // If re-initializing, clear buffer.
virtual nsresult Init() override;
// Can be called on any thread.
virtual nsresult WriteBlock(uint32_t aBlockIndex,
Span<const uint8_t> aData1,
Span<const uint8_t> aData2) override;
// Synchronously reads data from buffer.