Bug 961049 - Part 9: Fix asynchronous deletion of files to work on PBackground; r=baku

This commit is contained in:
Jan Varga 2015-11-22 10:44:43 +01:00
parent 736e2d562c
commit 01bc2fb8bb
4 changed files with 53 additions and 22 deletions

View File

@ -19206,11 +19206,15 @@ FactoryOp::Open()
{
// These services have to be started on the main thread currently.
if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) {
IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetOrCreate();
if (NS_WARN_IF(!mgr)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
mgr->NoteBackgroundThread(mOwningThread);
nsCOMPtr<mozIStorageService> ss;
if (NS_WARN_IF(!(ss = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID)))) {
IDB_REPORT_INTERNAL_ERR();

View File

@ -9,6 +9,7 @@
#include "nsIConsoleService.h"
#include "nsIDiskSpaceWatcher.h"
#include "nsIDOMWindow.h"
#include "nsIEventTarget.h"
#include "nsIFile.h"
#include "nsIObserverService.h"
#include "nsIScriptError.h"
@ -182,6 +183,8 @@ class DeleteFilesRunnable final
State_Completed
};
nsCOMPtr<nsIEventTarget> mBackgroundThread;
RefPtr<FileManager> mFileManager;
nsTArray<int64_t> mFileIds;
@ -193,9 +196,13 @@ class DeleteFilesRunnable final
State mState;
public:
DeleteFilesRunnable(FileManager* aFileManager,
DeleteFilesRunnable(nsIEventTarget* aBackgroundThread,
FileManager* aFileManager,
nsTArray<int64_t>& aFileIds);
void
Dispatch();
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIRUNNABLE
@ -735,6 +742,16 @@ IndexedDatabaseManager::ClearBackgroundActor()
mBackgroundActor = nullptr;
}
void
IndexedDatabaseManager::NoteBackgroundThread(nsIEventTarget* aBackgroundThread)
{
MOZ_ASSERT(IsMainProcess());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBackgroundThread);
mBackgroundThread = aBackgroundThread;
}
already_AddRefed<FileManager>
IndexedDatabaseManager::GetFileManager(PersistenceType aPersistenceType,
const nsACString& aOrigin,
@ -1029,11 +1046,11 @@ IndexedDatabaseManager::Notify(nsITimer* aTimer)
MOZ_ASSERT(!value->IsEmpty());
RefPtr<DeleteFilesRunnable> runnable =
new DeleteFilesRunnable(key, *value);
new DeleteFilesRunnable(mBackgroundThread, key, *value);
MOZ_ASSERT(value->IsEmpty());
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
runnable->Dispatch();
}
mPendingDeleteInfos.Clear();
@ -1145,14 +1162,26 @@ FileManagerInfo::GetArray(PersistenceType aPersistenceType)
}
}
DeleteFilesRunnable::DeleteFilesRunnable(FileManager* aFileManager,
DeleteFilesRunnable::DeleteFilesRunnable(nsIEventTarget* aBackgroundThread,
FileManager* aFileManager,
nsTArray<int64_t>& aFileIds)
: mFileManager(aFileManager)
: mBackgroundThread(aBackgroundThread)
, mFileManager(aFileManager)
, mState(State_Initial)
{
mFileIds.SwapElements(aFileIds);
}
void
DeleteFilesRunnable::Dispatch()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mState == State_Initial);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
mBackgroundThread->Dispatch(this, NS_DISPATCH_NORMAL)));
}
NS_IMPL_ISUPPORTS(DeleteFilesRunnable, nsIRunnable)
NS_IMETHODIMP
@ -1188,7 +1217,7 @@ DeleteFilesRunnable::Run()
void
DeleteFilesRunnable::DirectoryLockAcquired(DirectoryLock* aLock)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnBackgroundThread();
MOZ_ASSERT(mState == State_DirectoryOpenPending);
MOZ_ASSERT(!mDirectoryLock);
@ -1210,7 +1239,7 @@ DeleteFilesRunnable::DirectoryLockAcquired(DirectoryLock* aLock)
void
DeleteFilesRunnable::DirectoryLockFailed()
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnBackgroundThread();
MOZ_ASSERT(mState == State_DirectoryOpenPending);
MOZ_ASSERT(!mDirectoryLock);
@ -1220,7 +1249,7 @@ DeleteFilesRunnable::DirectoryLockFailed()
nsresult
DeleteFilesRunnable::Open()
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnBackgroundThread();
MOZ_ASSERT(mState == State_Initial);
QuotaManager* quotaManager = QuotaManager::Get();
@ -1315,18 +1344,17 @@ DeleteFilesRunnable::Finish()
// thread.
mState = State_UnblockingOpen;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(this)));
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
mBackgroundThread->Dispatch(this, NS_DISPATCH_NORMAL)));
}
void
DeleteFilesRunnable::UnblockOpen()
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnBackgroundThread();
MOZ_ASSERT(mState == State_UnblockingOpen);
if (mDirectoryLock) {
mDirectoryLock = nullptr;
}
mDirectoryLock = nullptr;
mState = State_Completed;
}

View File

@ -18,6 +18,7 @@
#include "nsHashKeys.h"
#include "nsITimer.h"
class nsIEventTarget;
struct PRLogModuleInfo;
namespace mozilla {
@ -125,6 +126,9 @@ public:
void
ClearBackgroundActor();
void
NoteBackgroundThread(nsIEventTarget* aBackgroundThread);
already_AddRefed<FileManager>
GetFileManager(PersistenceType aPersistenceType,
const nsACString& aOrigin,
@ -198,6 +202,8 @@ private:
static void
LoggingModePrefChangedCallback(const char* aPrefName, void* aClosure);
nsCOMPtr<nsIEventTarget> mBackgroundThread;
nsCOMPtr<nsITimer> mDeleteTimer;
// Maintains a list of all file managers per origin. This list isn't

View File

@ -83,14 +83,7 @@
scheduleGC();
yield undefined;
// This isn't really necessary but in order to ensure that our files have
// been deleted we need to round-trip with the PBackground thread...
let request = indexedDB.deleteDatabase(name + "this can't exist");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
yield undefined;
// and also flush pending file deletions before checking usage.
// Flush pending file deletions before checking usage.
flushPendingFileDeletions();
getUsage(grabFileUsageAndContinueHandler);