refactor: node::Environment self-cleanup (#39604)
* chore: savepoint * chore: turn raw_ptr tests back off
This commit is contained in:
parent
a8999bc529
commit
35969939a1
12 changed files with 95 additions and 83 deletions
|
@ -88,7 +88,7 @@ void ElectronRendererClient::DidCreateScriptContext(
|
|||
v8::Maybe<bool> initialized = node::InitializeContext(renderer_context);
|
||||
CHECK(!initialized.IsNothing() && initialized.FromJust());
|
||||
|
||||
node::Environment* env =
|
||||
std::shared_ptr<node::Environment> env =
|
||||
node_bindings_->CreateEnvironment(renderer_context, nullptr);
|
||||
|
||||
// If we have disabled the site instance overrides we should prevent loading
|
||||
|
@ -106,11 +106,11 @@ void ElectronRendererClient::DidCreateScriptContext(
|
|||
BindProcess(env->isolate(), &process_dict, render_frame);
|
||||
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(env);
|
||||
node_bindings_->LoadEnvironment(env.get());
|
||||
|
||||
if (node_bindings_->uv_env() == nullptr) {
|
||||
// Make uv loop being wrapped by window context.
|
||||
node_bindings_->set_uv_env(env);
|
||||
node_bindings_->set_uv_env(env.get());
|
||||
|
||||
// Give the node loop a run to make sure everything is ready.
|
||||
node_bindings_->StartPolling();
|
||||
|
@ -124,7 +124,9 @@ void ElectronRendererClient::WillReleaseScriptContext(
|
|||
return;
|
||||
|
||||
node::Environment* env = node::Environment::GetCurrent(context);
|
||||
if (environments_.erase(env) == 0)
|
||||
const auto iter = base::ranges::find_if(
|
||||
environments_, [env](auto& item) { return env == item.get(); });
|
||||
if (iter == environments_.end())
|
||||
return;
|
||||
|
||||
gin_helper::EmitEvent(env->isolate(), env->process_object(), "exit");
|
||||
|
@ -143,9 +145,7 @@ void ElectronRendererClient::WillReleaseScriptContext(
|
|||
DCHECK_EQ(microtask_queue->GetMicrotasksScopeDepth(), 0);
|
||||
microtask_queue->set_microtasks_policy(v8::MicrotasksPolicy::kExplicit);
|
||||
|
||||
node::FreeEnvironment(env);
|
||||
node::FreeIsolateData(node_bindings_->isolate_data(context));
|
||||
node_bindings_->clear_isolate_data(context);
|
||||
environments_.erase(iter);
|
||||
|
||||
microtask_queue->set_microtasks_policy(old_policy);
|
||||
|
||||
|
@ -201,7 +201,11 @@ node::Environment* ElectronRendererClient::GetEnvironment(
|
|||
auto context =
|
||||
GetContext(render_frame->GetWebFrame(), v8::Isolate::GetCurrent());
|
||||
node::Environment* env = node::Environment::GetCurrent(context);
|
||||
return base::Contains(environments_, env) ? env : nullptr;
|
||||
|
||||
return base::Contains(environments_, env,
|
||||
[](auto const& item) { return item.get(); })
|
||||
? env
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
|
|
@ -55,7 +55,7 @@ class ElectronRendererClient : public RendererClientBase {
|
|||
// The node::Environment::GetCurrent API does not return nullptr when it
|
||||
// is called for a context without node::Environment, so we have to keep
|
||||
// a book of the environments created.
|
||||
std::set<node::Environment*> environments_;
|
||||
std::set<std::shared_ptr<node::Environment>> environments_;
|
||||
|
||||
// Getting main script context from web frame would lazily initializes
|
||||
// its script context. Doing so in a web page without scripts would trigger
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
#include <utility>
|
||||
|
||||
#include "base/containers/cxx20_erase_set.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/ranges/algorithm.h"
|
||||
#include "base/threading/thread_local.h"
|
||||
#include "shell/common/api/electron_bindings.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
|
@ -61,20 +63,23 @@ void WebWorkerObserver::WorkerScriptReadyForEvaluation(
|
|||
// Setup node environment for each window.
|
||||
v8::Maybe<bool> initialized = node::InitializeContext(worker_context);
|
||||
CHECK(!initialized.IsNothing() && initialized.FromJust());
|
||||
node::Environment* env =
|
||||
std::shared_ptr<node::Environment> env =
|
||||
node_bindings_->CreateEnvironment(worker_context, nullptr);
|
||||
|
||||
// Add Electron extended APIs.
|
||||
electron_bindings_->BindTo(env->isolate(), env->process_object());
|
||||
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(env);
|
||||
node_bindings_->LoadEnvironment(env.get());
|
||||
|
||||
// Make uv loop being wrapped by window context.
|
||||
node_bindings_->set_uv_env(env);
|
||||
node_bindings_->set_uv_env(env.get());
|
||||
|
||||
// Give the node loop a run to make sure everything is ready.
|
||||
node_bindings_->StartPolling();
|
||||
|
||||
// Keep the environment alive until we free it in ContextWillDestroy()
|
||||
environments_.insert(std::move(env));
|
||||
}
|
||||
|
||||
void WebWorkerObserver::ContextWillDestroy(v8::Local<v8::Context> context) {
|
||||
|
@ -91,9 +96,8 @@ void WebWorkerObserver::ContextWillDestroy(v8::Local<v8::Context> context) {
|
|||
DCHECK_EQ(microtask_queue->GetMicrotasksScopeDepth(), 0);
|
||||
microtask_queue->set_microtasks_policy(v8::MicrotasksPolicy::kExplicit);
|
||||
|
||||
node::FreeEnvironment(env);
|
||||
node::FreeIsolateData(node_bindings_->isolate_data(context));
|
||||
node_bindings_->clear_isolate_data(context);
|
||||
base::EraseIf(environments_,
|
||||
[env](auto const& item) { return item.get() == env; });
|
||||
|
||||
microtask_queue->set_microtasks_policy(old_policy);
|
||||
|
||||
|
|
|
@ -6,9 +6,16 @@
|
|||
#define ELECTRON_SHELL_RENDERER_WEB_WORKER_OBSERVER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace node {
|
||||
|
||||
class Environment;
|
||||
|
||||
} // namespace node
|
||||
|
||||
namespace electron {
|
||||
|
||||
class ElectronBindings;
|
||||
|
@ -35,6 +42,7 @@ class WebWorkerObserver {
|
|||
private:
|
||||
std::unique_ptr<NodeBindings> node_bindings_;
|
||||
std::unique_ptr<ElectronBindings> electron_bindings_;
|
||||
std::set<std::shared_ptr<node::Environment>> environments_;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue