Bug 1349746 - Ensure we close media cache's temporary file if the cache shuts down while we're waiting for the FD to arrive. r=jwwang

MozReview-Commit-ID: HNXt3pYb1Iv

--HG--
extra : rebase_source : 5dccbbb4bf37bf31da145d70abab7373871a1413
This commit is contained in:
Chris Pearce 2017-04-07 17:51:47 +12:00
parent 8e0f8ac9e7
commit a11f81c232
2 changed files with 29 additions and 23 deletions

View File

@ -27,7 +27,6 @@ FileBlockCache::SetCacheFile(PRFileDesc* aFD)
if (!aFD) {
// Failed to get a temporary file. Shutdown.
mInitPromise->Reject(NS_ERROR_FAILURE, __func__);
Close();
return;
}
@ -35,7 +34,20 @@ FileBlockCache::SetCacheFile(PRFileDesc* aFD)
MonitorAutoLock lock(mFileMonitor);
mFD = aFD;
}
mInitPromise->Resolve(true, __func__);
{
MonitorAutoLock lock(mDataMonitor);
if (!mIsOpen) {
// We've been closed while waiting for the file descriptor. Bail out.
// Rely on the destructor to close the file descriptor.
return;
}
mInitialized = true;
if (mIsWriteScheduled) {
// A write was scheduled while waiting for FD. We need to dispatch a
// task to service the request.
mThread->Dispatch(this, NS_DISPATCH_NORMAL);
}
}
}
nsresult
@ -53,14 +65,12 @@ FileBlockCache::Init()
if (NS_FAILED(rv)) {
return rv;
}
mAbstractThread = AbstractThread::CreateXPCOMThreadWrapper(mThread, false);
mIsOpen = true;
mInitPromise = new GenericPromise::Private(__func__);
if (XRE_IsParentProcess()) {
rv = NS_OpenAnonymousTemporaryFile(&mFD);
if (NS_SUCCEEDED(rv)) {
mInitPromise->Resolve(true, __func__);
mInitialized = true;
}
} else {
// We must request a temporary file descriptor from the parent process.
@ -111,11 +121,13 @@ void FileBlockCache::Close()
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
MonitorAutoLock mon(mDataMonitor);
if (!mIsOpen) {
return;
}
mIsOpen = false;
if (!mThread) {
return;
}
mAbstractThread = nullptr;
// We must shut down the thread in another runnable. This is called
// while we're shutting down the media cache, and nsIThread::Shutdown()
// can cause events to run before it completes, which could end up
@ -173,14 +185,12 @@ void FileBlockCache::EnsureWriteScheduled()
return;
}
mIsWriteScheduled = true;
RefPtr<FileBlockCache> self = this;
mInitPromise->Then(mAbstractThread,
__func__,
[self](bool aValue) { self->Run(); },
[self](nsresult rv) {}
// Failure handled by EnsureInitialized.
);
if (!mInitialized) {
// We're still waiting on a file descriptor. When it arrives,
// the write will be scheduled.
return;
}
mThread->Dispatch(this, NS_DISPATCH_NORMAL);
}
nsresult FileBlockCache::Seek(int64_t aOffset)

View File

@ -163,12 +163,6 @@ private:
// has been dispatched to preform the IO.
// mDataMonitor must be owned while calling this.
void EnsureWriteScheduled();
// Promise that tracks the request for an anonymous temporary file for the
// cache to store data into. The file descriptor must be requested from the
// parent process when the cache is initialized. While this promise is
// outstanding, the FileBlockCache buffers blocks in memory, and reads
// against the cache are serviced from the in-memory buffers.
RefPtr<GenericPromise::Private> mInitPromise;
// Array of block changes to made. If mBlockChanges[offset/BLOCK_SIZE] == nullptr,
// then the block has no pending changes to be written, but if
@ -180,15 +174,17 @@ private:
// created upon open, and shutdown (asynchronously) upon close (on the
// main thread).
nsCOMPtr<nsIThread> mThread;
// Wrapper for mThread.
RefPtr<AbstractThread> mAbstractThread;
// Queue of pending block indexes that need to be written or moved.
std::deque<int32_t> mChangeIndexList;
// True if we've dispatched an event to commit all pending block changes
// to file on mThread.
bool mIsWriteScheduled;
// True if the writer is ready to write data to file.
// True if the writer is ready to enqueue writes.
bool mIsOpen;
// True if we've got a temporary file descriptor. Note: we don't use mFD
// directly as that's synchronized via mFileMonitor and we need to make
// decisions about whether we can write while holding mDataMonitor.
bool mInitialized = false;
};
} // End namespace mozilla.