зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1617709: Fix hang monitor init/shutdown race in short-lived processes. r=mccr8
Differential Revision: https://phabricator.services.mozilla.com/D72237
This commit is contained in:
Родитель
4c5b09e477
Коммит
4605b92d4f
|
@ -137,6 +137,12 @@ class HangMonitorChild : public PProcessHangMonitorChild,
|
|||
|
||||
void AnnotateHang(BackgroundHangAnnotations& aAnnotations) override;
|
||||
|
||||
protected:
|
||||
friend class mozilla::ProcessHangMonitor;
|
||||
static Maybe<Monitor> sMonitor;
|
||||
|
||||
static Atomic<bool, SequentiallyConsistent> sInitializing;
|
||||
|
||||
private:
|
||||
void ShutdownOnThread();
|
||||
|
||||
|
@ -173,6 +179,10 @@ class HangMonitorChild : public PProcessHangMonitorChild,
|
|||
Atomic<bool> mPaintWhileInterruptingJSActive;
|
||||
};
|
||||
|
||||
Maybe<Monitor> HangMonitorChild::sMonitor;
|
||||
|
||||
Atomic<bool, SequentiallyConsistent> HangMonitorChild::sInitializing;
|
||||
|
||||
Atomic<HangMonitorChild*, SequentiallyConsistent> HangMonitorChild::sInstance;
|
||||
|
||||
/* Parent process objects */
|
||||
|
@ -319,9 +329,17 @@ HangMonitorChild::HangMonitorChild(ProcessHangMonitor* aMonitor)
|
|||
mIPCOpen(true),
|
||||
mPaintWhileInterruptingJSActive(false) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!sInstance);
|
||||
mContext = danger::GetJSContext();
|
||||
|
||||
BackgroundHangMonitor::RegisterAnnotator(*this);
|
||||
|
||||
MOZ_ASSERT(!sMonitor.isSome());
|
||||
sMonitor.emplace("HangMonitorChild::sMonitor");
|
||||
MonitorAutoLock mal(*sMonitor);
|
||||
|
||||
MOZ_ASSERT(!sInitializing);
|
||||
sInitializing = true;
|
||||
}
|
||||
|
||||
HangMonitorChild::~HangMonitorChild() {
|
||||
|
@ -560,11 +578,16 @@ mozilla::ipc::IPCResult HangMonitorChild::RecvCancelContentJSExecutionIfRunning(
|
|||
void HangMonitorChild::Bind(Endpoint<PProcessHangMonitorChild>&& aEndpoint) {
|
||||
MOZ_RELEASE_ASSERT(IsOnThread());
|
||||
|
||||
MonitorAutoLock mal(*sMonitor);
|
||||
|
||||
MOZ_ASSERT(!sInstance);
|
||||
sInstance = this;
|
||||
|
||||
DebugOnly<bool> ok = aEndpoint.Bind(this);
|
||||
MOZ_ASSERT(ok);
|
||||
|
||||
sInitializing = false;
|
||||
mal.Notify();
|
||||
}
|
||||
|
||||
void HangMonitorChild::NotifySlowScriptAsync(TabId aTabId,
|
||||
|
@ -1227,15 +1250,21 @@ ProcessHangMonitor::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
const char16_t* aData) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
if (!strcmp(aTopic, "xpcom-shutdown")) {
|
||||
if (HangMonitorChild* child = HangMonitorChild::Get()) {
|
||||
child->Shutdown();
|
||||
delete child;
|
||||
if (HangMonitorChild::sMonitor) {
|
||||
MonitorAutoLock mal(*HangMonitorChild::sMonitor);
|
||||
if (HangMonitorChild::sInitializing) {
|
||||
mal.Wait();
|
||||
}
|
||||
|
||||
if (HangMonitorChild* child = HangMonitorChild::Get()) {
|
||||
child->Shutdown();
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
HangMonitorChild::sMonitor.reset();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, "xpcom-shutdown");
|
||||
}
|
||||
obs->RemoveObserver(this, "xpcom-shutdown");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче