mirror of
https://github.com/electron/electron.git
synced 2026-10-28 19:54:46 +08:00
* fix: give each renderer Node.js environment its own uv loop Same-process child windows and node-integrated subframes each get a Node.js environment, and until now all of them shared uv_default_loop() on the renderer main thread. Freeing one (FreeEnvironment runs the loop until that environment's handles close, with JavaScript disallowed on the isolate) therefore dispatched the other environments' pending immediates, timers, fs and threadpool callbacks in that window, which threw "Uncaught illegal access" in the surviving page or aborted the renderer (InternalCallbackScope / ToLocalChecked checks). NodeBindings can now integrate a given loop or own a fresh one (as the worker path already did), and the renderer keeps one NodeBindings + ElectronBindings pair per frame environment: the first borrows the process-lifetime uv_default_loop() integration so native modules that use the default loop keep working, later ones own their loop. Tearing an environment down parks that loop's embed thread and frees it without touching anyone else's handles. This also replaces the uv_env hand-off between main-frame environments and the injected-frames bookkeeping with a RenderFrame-keyed map, and gives each new environment its first loop run from a fresh task since child contexts can be created from inside a script. Fixes https://github.com/electron/electron/issues/36858 Fixes https://github.com/electron/electron/issues/40607 * fix: don't stack an error message listener per renderer environment CreateEnvironment adds Electron's V8 message listener for renderer and worker environments, and V8 keeps every listener it is given, so each navigation or child frame added another copy and uncaught errors ran the async-hook cleanup once per environment ever created on the isolate. Remove the previous registration before adding. Also restate why about:blank subframes are skipped for Node.js integration: freeing their environment is no longer a problem, but they commit synchronously in the renderer and so never receive the preload startup data the sandboxed bundle needs. * test: cover child-window loops, opener reloads and napi work across renderer environments Adds an async export to the echo fixture (a libuv threadpool round trip that calls back into JS, the napi path that aborted in InternalCallbackScope when it completed under another environment's context) and uses it to check that same-process child windows, including a synchronously created about:blank one, run immediates, fs and napi work on their own loop, that a child keeps working while its opener reloads, and that the survivor's napi callbacks still arrive when a sibling environment is freed. * test: cover napi thread-safe functions in child window environments A thread-safe function called from another thread reaches JS through a uv_async_t on its environment's loop and an AsyncResource::CallbackScope, so in a same-process child window it used to run under the opener's context and abort in InternalCallbackScope. Give the echo fixture a thread-safe variant and exercise it alongside the async work. Refs https://github.com/electron/electron/issues/33868 * refactor: set the isolate up for Node.js once per isolate Pull the IsolateSettings / SetIsolateUpForNode / host-import-callback block out of NodeBindings::CreateEnvironment into NodeBindings::SetUpIsolate, and call it once from each owner: the renderer client's one-time init, the WebWorkerObserver for its thread's isolate, and the browser and utility processes right after their single CreateEnvironment (node's snapshot path resets the isolate error handlers inside CreateEnvironment, so it has to follow it there). Renderer frames no longer re-run isolate setup or stack a message listener per environment. * fix: only lend uv_default_loop() to main frame environments Subframe environments always get a loop of their own; a main frame borrows the process's uv_default_loop() integration while no other environment holds it, so native modules that use the default loop see a consistent main-frame environment. * fix: free a frame's environment under the explicit microtasks policy Restore the explicit microtasks policy around freeing a frame's Node.js environment (its loop runs during teardown, see #33280), and only tear down when the released context is the environment's own. Teardown can now be reached from inside script (an iframe removed with element.remove()), so ExplicitMicrotasksScope no longer asserts a zero microtasks scope depth in the renderer; explicit checkpoints are no-ops there until the enclosing scope unwinds.
24 lines
568 B
C++
24 lines
568 B
C++
// Copyright (c) 2013 GitHub, Inc.
|
|
// Use of this source code is governed by the MIT license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef ELECTRON_SHELL_COMMON_NODE_BINDINGS_MAC_H_
|
|
#define ELECTRON_SHELL_COMMON_NODE_BINDINGS_MAC_H_
|
|
|
|
#include "shell/common/node_bindings.h"
|
|
|
|
namespace electron {
|
|
|
|
class NodeBindingsMac : public NodeBindings {
|
|
public:
|
|
NodeBindingsMac(BrowserEnvironment browser_env, uv_loop_t* loop);
|
|
|
|
private:
|
|
// NodeBindings
|
|
void PollEvents() override;
|
|
};
|
|
|
|
} // namespace electron
|
|
|
|
#endif // ELECTRON_SHELL_COMMON_NODE_BINDINGS_MAC_H_
|