Bug 1261491 - Intermittent test_quotaExceeded_recovery.js | application crashed [@ mozilla::dom::IndexedDatabaseManager::Notify]; r=khuey

This commit is contained in:
Jan Varga 2016-07-18 18:51:54 +02:00
Родитель 2c6b8dc9ef
Коммит a6c44c3242
8 изменённых файлов: 90 добавлений и 17 удалений

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

@ -8995,6 +8995,12 @@ public:
virtual void
ShutdownWorkThreads() override;
virtual void
DidInitialize(QuotaManager* aQuotaManager) override;
virtual void
WillShutdown() override;
private:
~QuotaClient();
@ -17413,6 +17419,26 @@ QuotaClient::ShutdownWorkThreads()
}
}
void
QuotaClient::DidInitialize(QuotaManager* aQuotaManager)
{
MOZ_ASSERT(NS_IsMainThread());
if (IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get()) {
mgr->NoteLiveQuotaManager(aQuotaManager);
}
}
void
QuotaClient::WillShutdown()
{
MOZ_ASSERT(NS_IsMainThread());
if (IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get()) {
mgr->NoteShuttingDownQuotaManager();
}
}
nsresult
QuotaClient::GetDirectory(PersistenceType aPersistenceType,
const nsACString& aOrigin, nsIFile** aDirectory)
@ -19930,14 +19956,12 @@ FactoryOp::Open()
{
// These services have to be started on the main thread currently.
IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetOrCreate();
if (NS_WARN_IF(!mgr)) {
IndexedDatabaseManager* mgr;
if (NS_WARN_IF(!(mgr = IndexedDatabaseManager::GetOrCreate()))) {
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();

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

@ -348,6 +348,10 @@ IndexedDatabaseManager::Init()
mDeleteTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
NS_ENSURE_STATE(mDeleteTimer);
if (QuotaManager* quotaManager = QuotaManager::Get()) {
NoteLiveQuotaManager(quotaManager);
}
}
Preferences::RegisterCallbackAndCall(AtomicBoolPrefChangedCallback,
@ -747,13 +751,24 @@ IndexedDatabaseManager::ClearBackgroundActor()
}
void
IndexedDatabaseManager::NoteBackgroundThread(nsIEventTarget* aBackgroundThread)
IndexedDatabaseManager::NoteLiveQuotaManager(QuotaManager* aQuotaManager)
{
MOZ_ASSERT(IsMainProcess());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBackgroundThread);
MOZ_ASSERT(aQuotaManager);
mBackgroundThread = aBackgroundThread;
mBackgroundThread = aQuotaManager->OwningThread();
}
void
IndexedDatabaseManager::NoteShuttingDownQuotaManager()
{
MOZ_ASSERT(IsMainProcess());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ALWAYS_SUCCEEDS(mDeleteTimer->Cancel());
mBackgroundThread = nullptr;
}
already_AddRefed<FileManager>
@ -852,6 +867,10 @@ IndexedDatabaseManager::AsyncDeleteFile(FileManager* aFileManager,
MOZ_ASSERT(aFileId > 0);
MOZ_ASSERT(mDeleteTimer);
if (!mBackgroundThread) {
return NS_OK;
}
nsresult rv = mDeleteTimer->Cancel();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -1043,6 +1062,7 @@ IndexedDatabaseManager::Notify(nsITimer* aTimer)
{
MOZ_ASSERT(IsMainProcess());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBackgroundThread);
for (auto iter = mPendingDeleteInfos.ConstIter(); !iter.Done(); iter.Next()) {
auto key = iter.Key();

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

@ -28,6 +28,12 @@ namespace dom {
class IDBFactory;
namespace quota {
class QuotaManager;
} // namespace quota
namespace indexedDB {
class BackgroundUtilsChild;
@ -41,6 +47,7 @@ class IndexedDatabaseManager final
, public nsITimerCallback
{
typedef mozilla::dom::quota::PersistenceType PersistenceType;
typedef mozilla::dom::quota::QuotaManager QuotaManager;
typedef mozilla::dom::indexedDB::FileManager FileManager;
typedef mozilla::dom::indexedDB::FileManagerInfo FileManagerInfo;
@ -128,7 +135,10 @@ public:
ClearBackgroundActor();
void
NoteBackgroundThread(nsIEventTarget* aBackgroundThread);
NoteLiveQuotaManager(QuotaManager* aQuotaManager);
void
NoteShuttingDownQuotaManager();
already_AddRefed<FileManager>
GetFileManager(PersistenceType aPersistenceType,

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

@ -2284,6 +2284,10 @@ CreateRunnable::RegisterObserver()
qms->NoteLiveManager(mManager);
for (RefPtr<Client>& client : mManager->mClients) {
client->DidInitialize(mManager);
}
return NS_OK;
}
@ -2387,11 +2391,6 @@ QuotaManager::
ShutdownRunnable::Run()
{
if (NS_IsMainThread()) {
QuotaManagerService* qms = QuotaManagerService::Get();
MOZ_ASSERT(qms);
qms->NoteFinishedManager();
mDone = true;
return NS_OK;
@ -2421,6 +2420,16 @@ ShutdownObserver::Observe(nsISupports* aSubject,
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!strcmp(aTopic, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID));
MOZ_ASSERT(gInstance);
QuotaManagerService* qms = QuotaManagerService::Get();
MOZ_ASSERT(qms);
qms->NoteShuttingDownManager();
for (RefPtr<Client>& client : gInstance->mClients) {
client->WillShutdown();
}
bool done = false;
@ -2751,8 +2760,6 @@ QuotaManager::GetOrCreate(nsIRunnable* aCallback)
QuotaManager*
QuotaManager::Get()
{
MOZ_ASSERT(!NS_IsMainThread());
// Does not return an owning reference.
return gInstance;
}

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

@ -21,6 +21,7 @@ class nsIRunnable;
BEGIN_QUOTA_NAMESPACE
class QuotaManager;
class UsageInfo;
// An abstract interface for quota manager clients.
@ -127,6 +128,15 @@ public:
virtual void
ShutdownWorkThreads() = 0;
// Methods which are called on the main thread.
virtual void
DidInitialize(QuotaManager* aQuotaManager)
{ }
virtual void
WillShutdown()
{ }
protected:
virtual ~Client()
{ }

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

@ -513,6 +513,8 @@ private:
// by any mutex but it is only ever touched on the IO thread.
nsTArray<nsCString> mInitializedOrigins;
// This array is populated at initialization time and then never modified, so
// it can be iterated on any thread.
AutoTArray<RefPtr<Client>, Client::TYPE_MAX> mClients;
nsString mBasePath;

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

@ -257,7 +257,7 @@ QuotaManagerService::NoteLiveManager(QuotaManager* aManager)
}
void
QuotaManagerService::NoteFinishedManager()
QuotaManagerService::NoteShuttingDownManager()
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());

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

@ -69,7 +69,7 @@ public:
NoteLiveManager(QuotaManager* aManager);
void
NoteFinishedManager();
NoteShuttingDownManager();
// Called when a process is being shot down. Aborts any running operations
// for the given process.