fix: utility process exit code for graceful termination (#44749)

This commit is contained in:
Robo 2024-11-20 23:23:10 +09:00 committed by GitHub
parent ee66bf9381
commit c90509c2bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 30 additions and 49 deletions

View file

@ -146,8 +146,8 @@ UtilityProcessWrapper::UtilityProcessWrapper(
}
}
if (!content::ServiceProcessHost::HasObserver(this))
content::ServiceProcessHost::AddObserver(this);
// Watch for service process termination events.
content::ServiceProcessHost::AddObserver(this);
mojo::PendingReceiver<node::mojom::NodeService> receiver =
node_service_remote_.BindNewPipeAndPassReceiver();
@ -257,6 +257,23 @@ void UtilityProcessWrapper::HandleTermination(uint64_t exit_code) {
pid_ = base::kNullProcessId;
CloseConnectorPort();
if (killed_) {
#if BUILDFLAG(IS_POSIX)
// UtilityProcessWrapper::Kill relies on base::Process::Terminate
// to gracefully shutdown the process which is performed by sending
// SIGTERM signal. When listening for exit events via ServiceProcessHost
// observers, the exit code on posix is obtained via
// BrowserChildProcessHostImpl::GetTerminationInfo which inturn relies
// on waitpid to extract the exit signal. If the process is unavailable,
// then the exit_code will be set to 0, otherwise we get the signal that
// was sent during the base::Process::Terminate call. For a user, this is
// still a graceful shutdown case so lets' convert the exit code to the
// expected value.
if (exit_code == SIGTERM || exit_code == SIGKILL) {
exit_code = 0;
}
#endif
}
EmitWithoutEvent("exit", exit_code);
Unpin();
}
@ -335,7 +352,7 @@ void UtilityProcessWrapper::PostMessage(gin::Arguments* args) {
connector_->Accept(&mojo_message);
}
bool UtilityProcessWrapper::Kill() const {
bool UtilityProcessWrapper::Kill() {
if (pid_ == base::kNullProcessId)
return false;
base::Process process = base::Process::Open(pid_);
@ -348,6 +365,7 @@ bool UtilityProcessWrapper::Kill() const {
// process reap should be signaled through the zygote via
// content::ZygoteCommunication::EnsureProcessTerminated.
base::EnsureProcessTerminated(std::move(process));
killed_ = result;
return result;
}

View file

@ -73,7 +73,7 @@ class UtilityProcessWrapper final
void HandleTermination(uint64_t exit_code);
void PostMessage(gin::Arguments* args);
bool Kill() const;
bool Kill();
v8::Local<v8::Value> GetOSProcessId(v8::Isolate* isolate) const;
// mojo::MessageReceiver
@ -99,6 +99,7 @@ class UtilityProcessWrapper final
int stderr_read_fd_ = -1;
bool connector_closed_ = false;
bool terminated_ = false;
bool killed_ = false;
std::unique_ptr<mojo::Connector> connector_;
blink::MessagePortDescriptor host_port_;
mojo::Remote<node::mojom::NodeService> node_service_remote_;