Bug 1736611 - Avoid creating runnables after SocketProcessHost is destroyed, r=necko-reviewers,dragana

Differential Revision: https://phabricator.services.mozilla.com/D131489
This commit is contained in:
Kershaw Chang 2021-11-23 20:13:09 +00:00
parent d7dd6f1294
commit f12dd38922
3 changed files with 31 additions and 9 deletions

View File

@ -628,9 +628,9 @@ void nsIOService::OnProcessLaunchComplete(SocketProcessHost* aHost,
LOG(("nsIOService::OnProcessLaunchComplete aSucceeded=%d\n", aSucceeded));
mSocketProcessLaunchComplete = true;
mSocketProcessLaunchComplete = aSucceeded;
if (mShutdown || !SocketProcessReady()) {
if (mShutdown || !SocketProcessReady() || !aSucceeded) {
return;
}

View File

@ -38,7 +38,7 @@ bool SocketProcessHost::sLaunchWithMacSandbox = false;
SocketProcessHost::SocketProcessHost(Listener* aListener)
: GeckoChildProcessHost(GeckoProcessType_Socket),
mListener(aListener),
mTaskFactory(this),
mTaskFactory(Some(this)),
mLaunchPhase(LaunchPhase::Unlaunched),
mShutdownRequested(false),
mChannelClosed(false) {
@ -78,6 +78,18 @@ bool SocketProcessHost::Launch() {
return true;
}
static void HandleErrorAfterDestroy(
RefPtr<SocketProcessHost::Listener>&& aListener) {
if (!aListener) {
return;
}
NS_DispatchToMainThread(NS_NewRunnableFunction(
"HandleErrorAfterDestroy", [listener = std::move(aListener)]() {
listener->OnProcessLaunchComplete(nullptr, false);
}));
}
void SocketProcessHost::OnChannelConnected(int32_t peer_pid) {
MOZ_ASSERT(!NS_IsMainThread());
@ -88,8 +100,13 @@ void SocketProcessHost::OnChannelConnected(int32_t peer_pid) {
RefPtr<Runnable> runnable;
{
MonitorAutoLock lock(mMonitor);
runnable = mTaskFactory.NewRunnableMethod(
&SocketProcessHost::OnChannelConnectedTask);
if (!mTaskFactory) {
HandleErrorAfterDestroy(std::move(mListener));
return;
}
runnable =
(*mTaskFactory)
.NewRunnableMethod(&SocketProcessHost::OnChannelConnectedTask);
}
NS_DispatchToMainThread(runnable);
}
@ -103,8 +120,12 @@ void SocketProcessHost::OnChannelError() {
RefPtr<Runnable> runnable;
{
MonitorAutoLock lock(mMonitor);
runnable =
mTaskFactory.NewRunnableMethod(&SocketProcessHost::OnChannelErrorTask);
if (!mTaskFactory) {
HandleErrorAfterDestroy(std::move(mListener));
return;
}
runnable = (*mTaskFactory)
.NewRunnableMethod(&SocketProcessHost::OnChannelErrorTask);
}
NS_DispatchToMainThread(runnable);
}
@ -223,7 +244,7 @@ void SocketProcessHost::OnChannelClosed() {
void SocketProcessHost::DestroyProcess() {
{
MonitorAutoLock lock(mMonitor);
mTaskFactory.RevokeAll();
mTaskFactory.reset();
}
GetCurrentSerialEventTarget()->Dispatch(NS_NewRunnableFunction(

View File

@ -6,6 +6,7 @@
#ifndef mozilla_net_SocketProcessHost_h
#define mozilla_net_SocketProcessHost_h
#include "mozilla/Maybe.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/MemoryReportingProcess.h"
@ -109,7 +110,7 @@ class SocketProcessHost final : public mozilla::ipc::GeckoChildProcessHost {
DISALLOW_COPY_AND_ASSIGN(SocketProcessHost);
RefPtr<Listener> mListener;
mozilla::ipc::TaskFactory<SocketProcessHost> mTaskFactory;
mozilla::Maybe<mozilla::ipc::TaskFactory<SocketProcessHost>> mTaskFactory;
enum class LaunchPhase { Unlaunched, Waiting, Complete };
LaunchPhase mLaunchPhase;