feat: UtilityProcess API (#34980)
* chore: initial scaffolding * chore: implement interface and docs * chore: address code style review * fix: cleanup of utility process on shutdown * chore: simplify NodeBindings::CreateEnvironment * chore: rename disableLibraryValidation => allowLoadingUnsignedLibraries * chore: implement process.parentPort * chore(posix): implement stdio pipe interface * chore(win): implement stdio interface * chore: reenable SetNodeOptions for utility process * chore: add specs * chore: fix lint * fix: update kill API * fix: update process.parentPort API * fix: exit event * docs: update exit event * fix: tests on linux * chore: expand on some comments * fix: shutdown of pipe reader Avoid logging since it is always the case that reader end of pipe will terminate after the child process. * fix: remove exit code check for crash spec * fix: rm PR_SET_NO_NEW_PRIVS for unsandbox utility process * chore: fix incorrect rebase * fix: address review feedback * chore: rename utility_process -> utility * chore: update docs * chore: cleanup c++ implemantation * fix: leak in NodeServiceHost impl * chore: minor cleanup * chore: cleanup JS implementation * chore: flip default stdio to inherit * fix: some api improvements * Support cwd option * Remove path restriction for modulePath * Rewire impl for env support * fix: add tests for cwd and env option * chore: alt impl for reading stdio handles * chore: support message queuing * chore: fix lint * chore: new UtilityProcess => utilityProcess.fork * fix: support for uncaught exception exits * chore: remove process.execArgv as default * fix: windows build * fix: style changes * fix: docs and style changes * chore: update patches * spec: disable flaky test on win32 arm CI Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
This commit is contained in:
parent
44c40efecf
commit
da0fd286b4
59 changed files with 2700 additions and 54 deletions
|
@ -24,13 +24,17 @@
|
|||
#include "components/os_crypt/key_storage_config_linux.h"
|
||||
#include "components/os_crypt/os_crypt.h"
|
||||
#include "content/browser/browser_main_loop.h" // nogncheck
|
||||
#include "content/public/browser/browser_child_process_host_delegate.h"
|
||||
#include "content/public/browser/browser_child_process_host_iterator.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/child_process_data.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/device_service.h"
|
||||
#include "content/public/browser/first_party_sets_handler.h"
|
||||
#include "content/public/browser/web_ui_controller_factory.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/process_type.h"
|
||||
#include "content/public/common/result_codes.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "electron/fuses.h"
|
||||
|
@ -39,6 +43,7 @@
|
|||
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
|
||||
#include "shell/app/electron_main_delegate.h"
|
||||
#include "shell/browser/api/electron_api_app.h"
|
||||
#include "shell/browser/api/electron_api_utility_process.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/browser_process_impl.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
|
@ -273,12 +278,15 @@ void ElectronBrowserMainParts::PostEarlyInitialization() {
|
|||
// Add Electron extended APIs.
|
||||
electron_bindings_->BindTo(js_env_->isolate(), env->process_object());
|
||||
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(env);
|
||||
// Create explicit microtasks runner.
|
||||
js_env_->CreateMicrotasksRunner();
|
||||
|
||||
// Wrap the uv loop with global env.
|
||||
node_bindings_->set_uv_env(env);
|
||||
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(env);
|
||||
|
||||
// We already initialized the feature list in PreEarlyInitialization(), but
|
||||
// the user JS script would not have had a chance to alter the command-line
|
||||
// switches at that point. Lets reinitialize it here to pick up the
|
||||
|
@ -503,7 +511,6 @@ int ElectronBrowserMainParts::PreMainMessageLoopRun() {
|
|||
|
||||
void ElectronBrowserMainParts::WillRunMainMessageLoop(
|
||||
std::unique_ptr<base::RunLoop>& run_loop) {
|
||||
js_env_->OnMessageLoopCreated();
|
||||
exit_code_ = content::RESULT_CODE_NORMAL_EXIT;
|
||||
Browser::Get()->SetMainMessageLoopQuitClosure(
|
||||
run_loop->QuitWhenIdleClosure());
|
||||
|
@ -565,10 +572,39 @@ void ElectronBrowserMainParts::PostMainMessageLoopRun() {
|
|||
}
|
||||
}
|
||||
|
||||
// Shutdown utility process created with Electron API before
|
||||
// stopping Node.js so that exit events can be emitted. We don't let
|
||||
// content layer perform this action since it destroys
|
||||
// child process only after this step (PostMainMessageLoopRun) via
|
||||
// BrowserProcessIOThread::ProcessHostCleanUp() which is too late for our
|
||||
// use case.
|
||||
// https://source.chromium.org/chromium/chromium/src/+/main:content/browser/browser_main_loop.cc;l=1086-1108
|
||||
//
|
||||
// The following logic is based on
|
||||
// https://source.chromium.org/chromium/chromium/src/+/main:content/browser/browser_process_io_thread.cc;l=127-159
|
||||
//
|
||||
// Although content::BrowserChildProcessHostIterator is only to be called from
|
||||
// IO thread, it is safe to call from PostMainMessageLoopRun because thread
|
||||
// restrictions have been lifted.
|
||||
// https://source.chromium.org/chromium/chromium/src/+/main:content/browser/browser_main_loop.cc;l=1062-1078
|
||||
for (content::BrowserChildProcessHostIterator it(
|
||||
content::PROCESS_TYPE_UTILITY);
|
||||
!it.Done(); ++it) {
|
||||
if (it.GetDelegate()->GetServiceName() == node::mojom::NodeService::Name_) {
|
||||
auto& process = it.GetData().GetProcess();
|
||||
if (!process.IsValid())
|
||||
continue;
|
||||
auto utility_process_wrapper =
|
||||
api::UtilityProcessWrapper::FromProcessId(process.Pid());
|
||||
if (utility_process_wrapper)
|
||||
utility_process_wrapper->Shutdown(0 /* exit_code */);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy node platform after all destructors_ are executed, as they may
|
||||
// invoke Node/V8 APIs inside them.
|
||||
node_env_->env()->set_trace_sync_io(false);
|
||||
js_env_->OnMessageLoopDestroying();
|
||||
js_env_->DestroyMicrotasksRunner();
|
||||
node::Stop(node_env_->env());
|
||||
node_env_.reset();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue