From 8cd777888a40e987ad536ab68421068f5c06d83b Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Fri, 9 Feb 2018 08:11:38 +0100 Subject: Fix a rare crash with asm.js caching. --- dom/indexedDB/ActorsParent.cpp | 96 +++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 21 deletions(-) (limited to 'dom/indexedDB') diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index c0cb69149..9d4e72f2f 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -18185,11 +18185,25 @@ QuotaClient::ShutdownWorkThreads() mShutdownRequested = true; + // Shutdown maintenance thread pool (this spins the event loop until all + // threads are gone). This should release any maintenance related quota + // objects. if (mMaintenanceThreadPool) { mMaintenanceThreadPool->Shutdown(); mMaintenanceThreadPool = nullptr; } + // Let any runnables dispatched from dying maintenance threads to be + // processed. This should release any maintenance related directory locks. + if (mCurrentMaintenance) { + nsIThread* currentThread = NS_GetCurrentThread(); + MOZ_ASSERT(currentThread); + + do { + MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread)); + } while (!mCurrentMaintenance); + } + RefPtr connectionPool = gConnectionPool.get(); if (connectionPool) { connectionPool->Shutdown(); @@ -18409,7 +18423,8 @@ Maintenance::Start() AssertIsOnBackgroundThread(); MOZ_ASSERT(mState == State::Initial); - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18433,7 +18448,8 @@ Maintenance::CreateIndexedDatabaseManager() MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mState == State::CreateIndexedDatabaseManager); - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18458,7 +18474,8 @@ Maintenance::OpenDirectory() MOZ_ASSERT(!mDirectoryLock); MOZ_ASSERT(QuotaManager::Get()); - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18482,7 +18499,8 @@ Maintenance::DirectoryOpen() MOZ_ASSERT(mState == State::DirectoryOpenPending); MOZ_ASSERT(mDirectoryLock); - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18512,7 +18530,8 @@ Maintenance::DirectoryWork() // We have to find all database files that match any persistence type and any // origin. We ignore anything out of the ordinary for now. - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18699,8 +18718,10 @@ Maintenance::DirectoryWork() continue; } + nsCString suffix; nsCString group; nsCString origin; + bool isApp; nsTArray databasePaths; while (true) { @@ -18756,19 +18777,18 @@ Maintenance::DirectoryWork() // Found a database. if (databasePaths.IsEmpty()) { + MOZ_ASSERT(suffix.IsEmpty()); MOZ_ASSERT(group.IsEmpty()); MOZ_ASSERT(origin.IsEmpty()); int64_t dummyTimeStamp; - nsCString dummySuffix; - bool dummyIsApp; if (NS_WARN_IF(NS_FAILED( quotaManager->GetDirectoryMetadata2(originDir, &dummyTimeStamp, - dummySuffix, + suffix, group, origin, - &dummyIsApp)))) { + &isApp)))) { // Not much we can do here... continue; } @@ -18784,6 +18804,22 @@ Maintenance::DirectoryWork() group, origin, Move(databasePaths))); + + nsCOMPtr directory; + + // Idle maintenance may occur before origin is initailized. + // Ensure origin is initialized first. It will initialize all origins + // for temporary storage including IDB origins. + rv = quotaManager->EnsureOriginIsInitialized(persistenceType, + suffix, + group, + origin, + isApp, + getter_AddRefs(directory)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } } } } @@ -18835,6 +18871,11 @@ Maintenance::BeginDatabaseMaintenance() } }; + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || + IsAborted()) { + return NS_ERROR_ABORT; + } + RefPtr threadPool; for (DirectoryInfo& directoryInfo : mDirectoryInfos) { @@ -19021,6 +19062,11 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() } }; + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return; + } + nsCOMPtr databaseFile = GetFileForPath(mDatabasePath); MOZ_ASSERT(databaseFile); @@ -19037,10 +19083,6 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() AutoClose autoClose(connection); - if (mMaintenance->IsAborted()) { - return; - } - AutoProgressHandler progressHandler(mMaintenance); if (NS_WARN_IF(NS_FAILED(progressHandler.Register(connection)))) { return; @@ -19059,20 +19101,12 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() return; } - if (mMaintenance->IsAborted()) { - return; - } - MaintenanceAction maintenanceAction; rv = DetermineMaintenanceAction(connection, databaseFile, &maintenanceAction); if (NS_WARN_IF(NS_FAILED(rv))) { return; } - if (mMaintenance->IsAborted()) { - return; - } - switch (maintenanceAction) { case MaintenanceAction::Nothing: break; @@ -19099,6 +19133,11 @@ DatabaseMaintenance::CheckIntegrity(mozIStorageConnection* aConnection, MOZ_ASSERT(aConnection); MOZ_ASSERT(aOk); + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return NS_ERROR_ABORT; + } + nsresult rv; // First do a full integrity_check. Scope statements tightly here because @@ -19216,6 +19255,11 @@ DatabaseMaintenance::DetermineMaintenanceAction( MOZ_ASSERT(aDatabaseFile); MOZ_ASSERT(aMaintenanceAction); + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return NS_ERROR_ABORT; + } + int32_t schemaVersion; nsresult rv = aConnection->GetSchemaVersion(&schemaVersion); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -19425,6 +19469,11 @@ DatabaseMaintenance::IncrementalVacuum(mozIStorageConnection* aConnection) MOZ_ASSERT(!IsOnBackgroundThread()); MOZ_ASSERT(aConnection); + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return; + } + nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "PRAGMA incremental_vacuum;" )); @@ -19442,6 +19491,11 @@ DatabaseMaintenance::FullVacuum(mozIStorageConnection* aConnection, MOZ_ASSERT(aConnection); MOZ_ASSERT(aDatabaseFile); + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return; + } + nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "VACUUM;" )); -- cgit v1.2.3