зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1880590 - Fix benign data race during fork server shutdown. r=nika
There's a race between `ProcessWatcher` checking if the fork server is in use (via `ForkServiceChild::Get`) and the fork server shutdown path (`ForkServerLauncher::Observe` calling `StopForkServer`). The race seems to be benign, but it causes test failures under TSan. As a relatively simple fix, this patch changes `ProcessWatcher` to check an atomic flag which is true if the fork server has ever been run. (This also means that, in the case where the fork server has been shut down but some of its child processes are still running, we will continue to use the `kill(pid, 0)` fallback.) Differential Revision: https://phabricator.services.mozilla.com/D203077
This commit is contained in:
Родитель
4963aba94b
Коммит
48864d54a3
|
@ -198,7 +198,7 @@ void CloseSuperfluousFds(void* aCtx, bool (*aShouldPreserve)(void*, int)) {
|
|||
bool IsProcessDead(ProcessHandle handle, bool blocking) {
|
||||
auto handleForkServer = [handle]() -> mozilla::Maybe<bool> {
|
||||
#ifdef MOZ_ENABLE_FORKSERVER
|
||||
if (errno == ECHILD && mozilla::ipc::ForkServiceChild::Get()) {
|
||||
if (errno == ECHILD && mozilla::ipc::ForkServiceChild::WasUsed()) {
|
||||
// We only know if a process exists, but not if it has crashed.
|
||||
//
|
||||
// Since content processes are not direct children of the chrome
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ForkServiceChild.h"
|
||||
#include "ForkServer.h"
|
||||
#include "mozilla/ipc/IPDLParamTraits.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "mozilla/ipc/IPDLParamTraits.h"
|
||||
#include "mozilla/ipc/ProtocolMessageUtils.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
@ -23,6 +25,7 @@ namespace ipc {
|
|||
extern LazyLogModule gForkServiceLog;
|
||||
|
||||
mozilla::UniquePtr<ForkServiceChild> ForkServiceChild::sForkServiceChild;
|
||||
Atomic<bool> ForkServiceChild::sForkServiceUsed;
|
||||
|
||||
static bool ConfigurePipeFd(int aFd) {
|
||||
int flags = fcntl(aFd, F_GETFD, 0);
|
||||
|
@ -55,6 +58,7 @@ void ForkServiceChild::StartForkServer() {
|
|||
return;
|
||||
}
|
||||
|
||||
sForkServiceUsed = true;
|
||||
sForkServiceChild =
|
||||
mozilla::MakeUnique<ForkServiceChild>(server.release(), subprocess);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,11 @@ class ForkServiceChild {
|
|||
return child == nullptr || child->mFailed ? nullptr : child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the fork server was ever active. Thread-safe.
|
||||
*/
|
||||
static bool WasUsed() { return sForkServiceUsed; }
|
||||
|
||||
private:
|
||||
// Called when a message is received.
|
||||
void OnMessageReceived(UniquePtr<IPC::Message> message);
|
||||
|
@ -81,6 +86,7 @@ class ForkServiceChild {
|
|||
|
||||
UniquePtr<MiniTransceiver> mTcver;
|
||||
static UniquePtr<ForkServiceChild> sForkServiceChild;
|
||||
static Atomic<bool> sForkServiceUsed;
|
||||
pid_t mRecvPid;
|
||||
bool mFailed; // The forkserver has crashed or disconnected.
|
||||
GeckoChildProcessHost* mProcess;
|
||||
|
|
Загрузка…
Ссылка в новой задаче