mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1637085: Use AsyncShutdown for ContentParent shutdown. r=nika
Differential Revision: https://phabricator.services.mozilla.com/D74746
This commit is contained in:
parent
1c96455b0f
commit
28deb15a56
@ -616,8 +616,6 @@ static bool sCreatedFirstContentProcess = false;
|
||||
static uint64_t gContentChildID = 1;
|
||||
|
||||
static const char* sObserverTopics[] = {
|
||||
"xpcom-shutdown",
|
||||
"profile-before-change",
|
||||
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
|
||||
NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC,
|
||||
NS_IPC_CAPTIVE_PORTAL_SET_STATE,
|
||||
@ -1473,6 +1471,8 @@ void ContentParent::Init() {
|
||||
}
|
||||
}
|
||||
|
||||
AddShutdownBlockers();
|
||||
|
||||
// Flush any pref updates that happened during launch and weren't
|
||||
// included in the blobs set up in BeginSubprocessLaunch.
|
||||
for (const Pref& pref : mQueuedPrefs) {
|
||||
@ -1724,6 +1724,8 @@ void ContentParent::ActorDestroy(ActorDestroyReason why) {
|
||||
// finish waiting in the xpcom-shutdown/profile-before-change observer.
|
||||
mIPCOpen = false;
|
||||
|
||||
RemoveShutdownBlockers();
|
||||
|
||||
if (mHangMonitorActor) {
|
||||
ProcessHangMonitor::RemoveProcess(mHangMonitorActor);
|
||||
mHangMonitorActor = nullptr;
|
||||
@ -3081,30 +3083,79 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentParent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionErrorCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAsyncShutdownBlocker)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentParent)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
// Async shutdown blocker
|
||||
NS_IMETHODIMP
|
||||
ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
if (mSubprocess && (!strcmp(aTopic, "profile-before-change") ||
|
||||
!strcmp(aTopic, "xpcom-shutdown"))) {
|
||||
ContentParent::BlockShutdown(nsIAsyncShutdownClient* aClient) {
|
||||
// Make sure that our process will get scheduled.
|
||||
ProcessPriorityManager::SetProcessPriority(this,
|
||||
PROCESS_PRIORITY_FOREGROUND);
|
||||
ProcessPriorityManager::SetProcessPriority(this, PROCESS_PRIORITY_FOREGROUND);
|
||||
|
||||
// Okay to call ShutDownProcess multiple times.
|
||||
ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
|
||||
MarkAsDead();
|
||||
|
||||
// Wait for shutdown to complete, so that we receive any shutdown
|
||||
// data (e.g. telemetry) from the child before we quit.
|
||||
// This loop terminate prematurely based on mForceKillTimer.
|
||||
SpinEventLoopUntil([&]() { return !mIPCOpen || mCalledKillHard; });
|
||||
NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentParent::GetName(nsAString& aName) {
|
||||
aName.AssignLiteral("ContentParent:");
|
||||
aName.AppendPrintf(" id=%p", this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentParent::GetState(nsIPropertyBag** aResult) {
|
||||
auto props = MakeRefPtr<nsHashPropertyBag>();
|
||||
props->SetPropertyAsAString(NS_LITERAL_STRING("remoteTypePrefix"),
|
||||
RemoteTypePrefix(mRemoteType));
|
||||
*aResult = props.forget().downcast<nsIWritablePropertyBag>().take();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static StaticRefPtr<nsIAsyncShutdownClient> sXPCOMShutdownClient;
|
||||
static StaticRefPtr<nsIAsyncShutdownClient> sProfileBeforeChangeClient;
|
||||
|
||||
static void InitClients() {
|
||||
if (!sXPCOMShutdownClient) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
|
||||
|
||||
nsCOMPtr<nsIAsyncShutdownClient> client;
|
||||
rv = svc->GetXpcomWillShutdown(getter_AddRefs(client));
|
||||
sXPCOMShutdownClient = client.forget();
|
||||
ClearOnShutdown(&sXPCOMShutdownClient);
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv), "XPCOMShutdown shutdown blocker");
|
||||
|
||||
rv = svc->GetProfileBeforeChange(getter_AddRefs(client));
|
||||
sProfileBeforeChangeClient = client.forget();
|
||||
ClearOnShutdown(&sProfileBeforeChangeClient);
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv),
|
||||
"profileBeforeChange shutdown blocker");
|
||||
}
|
||||
}
|
||||
|
||||
void ContentParent::AddShutdownBlockers() {
|
||||
InitClients();
|
||||
|
||||
sXPCOMShutdownClient->AddBlocker(this, NS_LITERAL_STRING(__FILE__), __LINE__,
|
||||
EmptyString());
|
||||
sProfileBeforeChangeClient->AddBlocker(this, NS_LITERAL_STRING(__FILE__),
|
||||
__LINE__, EmptyString());
|
||||
}
|
||||
|
||||
void ContentParent::RemoveShutdownBlockers() {
|
||||
Unused << sXPCOMShutdownClient->RemoveBlocker(this);
|
||||
Unused << sProfileBeforeChangeClient->RemoveBlocker(this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
if (IsDead() || !mSubprocess) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -3545,6 +3596,8 @@ void ContentParent::KillHard(const char* aReason) {
|
||||
mCalledKillHard = true;
|
||||
mForceKillTimer = nullptr;
|
||||
|
||||
RemoveShutdownBlockers();
|
||||
|
||||
GeneratePairedMinidump(aReason);
|
||||
|
||||
nsDependentCString reason(aReason);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "nsPluginTags.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsIAsyncShutdown.h"
|
||||
#include "nsIContentParent.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIObserver.h"
|
||||
@ -132,6 +133,7 @@ class ContentParent final
|
||||
public nsIObserver,
|
||||
public nsIDOMGeoPositionCallback,
|
||||
public nsIDOMGeoPositionErrorCallback,
|
||||
public nsIAsyncShutdownBlocker,
|
||||
public nsIInterfaceRequestor,
|
||||
public gfx::gfxVarReceiver,
|
||||
public mozilla::LinkedListElement<ContentParent>,
|
||||
@ -340,6 +342,7 @@ class ContentParent final
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIDOMGEOPOSITIONCALLBACK
|
||||
NS_DECL_NSIDOMGEOPOSITIONERRORCALLBACK
|
||||
NS_DECL_NSIASYNCSHUTDOWNBLOCKER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
/**
|
||||
@ -704,6 +707,9 @@ class ContentParent final
|
||||
sJSPluginContentParents;
|
||||
static StaticAutoPtr<LinkedList<ContentParent>> sContentParents;
|
||||
|
||||
void AddShutdownBlockers();
|
||||
void RemoveShutdownBlockers();
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
|
||||
// Cached Mac sandbox params used when launching content processes.
|
||||
static StaticAutoPtr<std::vector<std::string>> sMacSandboxParams;
|
||||
|
Loading…
Reference in New Issue
Block a user