diff --git a/gfx/ipc/GPUChild.cpp b/gfx/ipc/GPUChild.cpp index 1f5b8743c42b..4557c40f6aad 100644 --- a/gfx/ipc/GPUChild.cpp +++ b/gfx/ipc/GPUChild.cpp @@ -103,6 +103,8 @@ base::ProcessHandle GPUChild::GetChildProcessHandle() { return mHost->GetChildProcessHandle(); } +void GPUChild::OnUnexpectedShutdown() { mUnexpectedShutdown = true; } + mozilla::ipc::IPCResult GPUChild::RecvInitComplete(const GPUDeviceData& aData) { // We synchronously requested GPU parameters before this arrived. if (mGPUReady) { @@ -265,7 +267,7 @@ mozilla::ipc::IPCResult GPUChild::RecvAddMemoryReport( } void GPUChild::ActorDestroy(ActorDestroyReason aWhy) { - if (aWhy == AbnormalShutdown) { + if (aWhy == AbnormalShutdown || mUnexpectedShutdown) { nsAutoString dumpId; GenerateCrashReport(OtherPid(), &dumpId); diff --git a/gfx/ipc/GPUChild.h b/gfx/ipc/GPUChild.h index 021bd216700e..2e61e1617dd4 100644 --- a/gfx/ipc/GPUChild.h +++ b/gfx/ipc/GPUChild.h @@ -35,6 +35,13 @@ class GPUChild final : public ipc::CrashReporterHelper, bool EnsureGPUReady(); base::ProcessHandle GetChildProcessHandle(); + // Notifies that an unexpected GPU process shutdown has been noticed by a + // different IPDL actor, and the GPU process is being torn down as a result. + // ActorDestroy may receive either NormalShutdown or AbnormalShutdown as a + // reason, depending on timings, but either way we treat the shutdown as + // abnormal. + void OnUnexpectedShutdown(); + // gfxVarReceiver overrides. void OnVarChanged(const GfxVarUpdate& aVar) override; @@ -85,6 +92,7 @@ class GPUChild final : public ipc::CrashReporterHelper, GPUProcessHost* mHost; UniquePtr mMemoryReportRequest; bool mGPUReady; + bool mUnexpectedShutdown = false; }; } // namespace gfx diff --git a/gfx/ipc/GPUProcessHost.cpp b/gfx/ipc/GPUProcessHost.cpp index a68ebbf0cd48..09a9dbd7d052 100644 --- a/gfx/ipc/GPUProcessHost.cpp +++ b/gfx/ipc/GPUProcessHost.cpp @@ -170,7 +170,7 @@ void GPUProcessHost::InitAfterConnect(bool aSucceeded) { } } -void GPUProcessHost::Shutdown() { +void GPUProcessHost::Shutdown(bool aUnexpectedShutdown) { MOZ_ASSERT(!mShutdownRequested); mListener = nullptr; @@ -180,6 +180,10 @@ void GPUProcessHost::Shutdown() { // unexpected. mShutdownRequested = true; + if (aUnexpectedShutdown) { + mGPUChild->OnUnexpectedShutdown(); + } + // The channel might already be closed if we got here unexpectedly. if (!mChannelClosed) { if (VRGPUChild::IsCreated()) { diff --git a/gfx/ipc/GPUProcessHost.h b/gfx/ipc/GPUProcessHost.h index cd86beafebd8..ad0c1c1ee478 100644 --- a/gfx/ipc/GPUProcessHost.h +++ b/gfx/ipc/GPUProcessHost.h @@ -77,7 +77,11 @@ class GPUProcessHost final : public mozilla::ipc::GeckoChildProcessHost { // GPUProcessHost. // // After this returns, the attached Listener is no longer used. - void Shutdown(); + // + // Setting aUnexpectedShutdown = true indicates that this is being called to + // clean up resources in response to an unexpected shutdown having been + // detected. + void Shutdown(bool aUnexpectedShutdown = false); // Return the actor for the top-level actor of the process. If the process // has not connected yet, this returns null. diff --git a/gfx/ipc/GPUProcessManager.cpp b/gfx/ipc/GPUProcessManager.cpp index b5294a5f0915..ae7edabcfac8 100644 --- a/gfx/ipc/GPUProcessManager.cpp +++ b/gfx/ipc/GPUProcessManager.cpp @@ -642,7 +642,7 @@ void GPUProcessManager::OnProcessUnexpectedShutdown(GPUProcessHost* aHost) { } CompositorManagerChild::OnGPUProcessLost(aHost->GetProcessToken()); - DestroyProcess(); + DestroyProcess(/* aUnexpectedShutdown */ true); if (mUnstableProcessAttempts > uint32_t(StaticPrefs::layers_gpu_process_max_restarts())) { @@ -812,12 +812,12 @@ void GPUProcessManager::KillProcess() { mProcess->KillProcess(); } -void GPUProcessManager::DestroyProcess() { +void GPUProcessManager::DestroyProcess(bool aUnexpectedShutdown) { if (!mProcess) { return; } - mProcess->Shutdown(); + mProcess->Shutdown(aUnexpectedShutdown); mProcessToken = 0; mProcess = nullptr; mGPUChild = nullptr; diff --git a/gfx/ipc/GPUProcessManager.h b/gfx/ipc/GPUProcessManager.h index 9d9ff0d13ba7..d4f6a3d29071 100644 --- a/gfx/ipc/GPUProcessManager.h +++ b/gfx/ipc/GPUProcessManager.h @@ -252,7 +252,11 @@ class GPUProcessManager final : public GPUProcessHost::Listener { // Shutdown the GPU process. void CleanShutdown(); - void DestroyProcess(); + // Destroy the process and clean up resources. + // Setting aUnexpectedShutdown = true indicates that this is being called to + // clean up resources in response to an unexpected shutdown having been + // detected. + void DestroyProcess(bool aUnexpectedShutdown = false); void HandleProcessLost();