mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 1526891 - Part 12: Merge ShutdownObserver with Observer; r=asuth
Differential Revision: https://phabricator.services.mozilla.com/D20921
This commit is contained in:
parent
863112a0eb
commit
64174bb9d6
@ -28,6 +28,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
|
#include "mozilla/AutoRestore.h"
|
||||||
#include "mozilla/BasePrincipal.h"
|
#include "mozilla/BasePrincipal.h"
|
||||||
#include "mozilla/CondVar.h"
|
#include "mozilla/CondVar.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
@ -480,28 +481,20 @@ class QuotaManager::ShutdownRunnable final : public Runnable {
|
|||||||
NS_DECL_NSIRUNNABLE
|
NS_DECL_NSIRUNNABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
class QuotaManager::ShutdownObserver final : public nsIObserver {
|
|
||||||
nsCOMPtr<nsIEventTarget> mBackgroundThread;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ShutdownObserver(nsIEventTarget* aBackgroundThread)
|
|
||||||
: mBackgroundThread(aBackgroundThread) {
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
NS_DECL_NSIOBSERVER
|
|
||||||
|
|
||||||
private:
|
|
||||||
~ShutdownObserver() { MOZ_ASSERT(NS_IsMainThread()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class QuotaManager::Observer final : public nsIObserver {
|
class QuotaManager::Observer final : public nsIObserver {
|
||||||
|
static Observer* sInstance;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
|
||||||
|
bool mPendingProfileChange;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static nsresult Initialize();
|
static nsresult Initialize();
|
||||||
|
|
||||||
|
static nsresult SetBackgroundEventTarget(
|
||||||
|
nsIEventTarget* aBackgroundEventTarget);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Observer() { MOZ_ASSERT(NS_IsMainThread()); }
|
Observer() : mPendingProfileChange(false) { MOZ_ASSERT(NS_IsMainThread()); }
|
||||||
|
|
||||||
~Observer() { MOZ_ASSERT(NS_IsMainThread()); }
|
~Observer() { MOZ_ASSERT(NS_IsMainThread()); }
|
||||||
|
|
||||||
@ -2346,16 +2339,7 @@ nsresult QuotaManager::CreateRunnable::RegisterObserver() {
|
|||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mState == State::RegisteringObserver);
|
MOZ_ASSERT(mState == State::RegisteringObserver);
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> observerService =
|
nsresult rv = Observer::SetBackgroundEventTarget(mOwningThread);
|
||||||
mozilla::services::GetObserverService();
|
|
||||||
if (NS_WARN_IF(!observerService)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIObserver> observer = new ShutdownObserver(mOwningThread);
|
|
||||||
|
|
||||||
nsresult rv = observerService->AddObserver(
|
|
||||||
observer, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID, false);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -2477,39 +2461,7 @@ QuotaManager::ShutdownRunnable::Run() {
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(QuotaManager::ShutdownObserver, nsIObserver)
|
QuotaManager::Observer* QuotaManager::Observer::sInstance = nullptr;
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
QuotaManager::ShutdownObserver::Observe(nsISupports* aSubject,
|
|
||||||
const char* aTopic,
|
|
||||||
const char16_t* aData) {
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(!strcmp(aTopic, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID));
|
|
||||||
MOZ_ASSERT(gInstance);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> observerService =
|
|
||||||
mozilla::services::GetObserverService();
|
|
||||||
if (NS_WARN_IF(!observerService)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unregister ourselves from the observer service first to make sure the
|
|
||||||
// nested event loop below will not cause re-entrancy issues.
|
|
||||||
Unused << observerService->RemoveObserver(
|
|
||||||
this, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID);
|
|
||||||
|
|
||||||
bool done = false;
|
|
||||||
|
|
||||||
RefPtr<ShutdownRunnable> shutdownRunnable = new ShutdownRunnable(done);
|
|
||||||
MOZ_ALWAYS_SUCCEEDS(
|
|
||||||
mBackgroundThread->Dispatch(shutdownRunnable, NS_DISPATCH_NORMAL));
|
|
||||||
|
|
||||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return done; }));
|
|
||||||
|
|
||||||
gBaseDirPath.Truncate();
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
nsresult QuotaManager::Observer::Initialize() {
|
nsresult QuotaManager::Observer::Initialize() {
|
||||||
@ -2522,6 +2474,19 @@ nsresult QuotaManager::Observer::Initialize() {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sInstance = observer;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
nsresult QuotaManager::Observer::SetBackgroundEventTarget(
|
||||||
|
nsIEventTarget* aBackgroundEventTarget) {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(sInstance);
|
||||||
|
|
||||||
|
sInstance->mBackgroundEventTarget = aBackgroundEventTarget;
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2544,6 +2509,13 @@ nsresult QuotaManager::Observer::Init() {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = obs->AddObserver(this, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
obs->RemoveObserver(this, kProfileDoChangeTopic);
|
||||||
|
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2555,9 +2527,13 @@ nsresult QuotaManager::Observer::Shutdown() {
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_SUCCEEDS(
|
||||||
|
obs->RemoveObserver(this, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID));
|
||||||
MOZ_ALWAYS_SUCCEEDS(obs->RemoveObserver(this, kProfileDoChangeTopic));
|
MOZ_ALWAYS_SUCCEEDS(obs->RemoveObserver(this, kProfileDoChangeTopic));
|
||||||
MOZ_ALWAYS_SUCCEEDS(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID));
|
MOZ_ALWAYS_SUCCEEDS(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID));
|
||||||
|
|
||||||
|
sInstance = nullptr;
|
||||||
|
|
||||||
// In general, the instance will have died after the latter removal call, so
|
// In general, the instance will have died after the latter removal call, so
|
||||||
// it's not safe to do anything after that point.
|
// it's not safe to do anything after that point.
|
||||||
// However, Shutdown is currently called from Observe which is called by the
|
// However, Shutdown is currently called from Observe which is called by the
|
||||||
@ -2596,6 +2572,32 @@ QuotaManager::Observer::Observe(nsISupports* aSubject, const char* aTopic,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID)) {
|
||||||
|
// mBackgroundThread can be null if we somehow get here without
|
||||||
|
// receiving SetBackgroundEventTarget() first. mPendingProfileChange is our
|
||||||
|
// re-entrancy guard (the nested event loop below may cause re-entrancy).
|
||||||
|
if (!mBackgroundEventTarget || mPendingProfileChange) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoRestore<bool> pending(mPendingProfileChange);
|
||||||
|
mPendingProfileChange = true;
|
||||||
|
|
||||||
|
MOZ_ASSERT(gInstance);
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
RefPtr<ShutdownRunnable> shutdownRunnable = new ShutdownRunnable(done);
|
||||||
|
MOZ_ALWAYS_SUCCEEDS(
|
||||||
|
mBackgroundEventTarget->Dispatch(shutdownRunnable, NS_DISPATCH_NORMAL));
|
||||||
|
|
||||||
|
MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return done; }));
|
||||||
|
|
||||||
|
gBaseDirPath.Truncate();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||||
rv = Shutdown();
|
rv = Shutdown();
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
@ -100,7 +100,6 @@ class QuotaManager final : public BackgroundThreadObject {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
class ShutdownRunnable;
|
class ShutdownRunnable;
|
||||||
class ShutdownObserver;
|
|
||||||
class Observer;
|
class Observer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user