File tree Expand file tree Collapse file tree 3 files changed +32
-6
lines changed
Expand file tree Collapse file tree 3 files changed +32
-6
lines changed Original file line number Diff line number Diff line change @@ -276,9 +276,16 @@ Environment::~Environment() {
276276 TRACE_EVENT_NESTABLE_ASYNC_END0 (
277277 TRACING_CATEGORY_NODE1 (environment), " Environment" , this );
278278
279- // Dereference all addons that were loaded into this environment.
280- for (binding::DLib& addon : loaded_addons_) {
281- addon.Close ();
279+ // Do not unload addons on the main thread. Some addons need to retain memory
280+ // beyond the Environment's lifetime, and unloading them early would break
281+ // them; with Worker threads, we have the opportunity to be stricter.
282+ // Also, since the main thread usually stops just before the process exits,
283+ // this is far less relevant here.
284+ if (!is_main_thread ()) {
285+ // Dereference all addons that were loaded into this environment.
286+ for (binding::DLib& addon : loaded_addons_) {
287+ addon.Close ();
288+ }
282289 }
283290}
284291
Original file line number Diff line number Diff line change 33#include < stdio.h>
44#include < stdlib.h>
55#include < v8.h>
6+ #include < uv.h>
67
78using v8::Context;
89using v8::HandleScope;
@@ -41,6 +42,17 @@ void Initialize(Local<Object> exports,
4142 const_cast <void *>(static_cast <const void *>(" cleanup" )));
4243 node::AddEnvironmentCleanupHook (context->GetIsolate (), Dummy, nullptr );
4344 node::RemoveEnvironmentCleanupHook (context->GetIsolate (), Dummy, nullptr );
45+
46+ if (getenv (" addExtraItemToEventLoop" ) != nullptr ) {
47+ // Add an item to the event loop that we do not clean up in order to make
48+ // sure that for the main thread, this addon's memory persists even after
49+ // the Environment instance has been destroyed.
50+ static uv_async_t extra_async;
51+ uv_loop_t * loop = node::GetCurrentEventLoop (context->GetIsolate ());
52+ int err = uv_async_init (loop, &extra_async, [](uv_async_t *) {});
53+ assert (err == 0 );
54+ uv_unref (reinterpret_cast <uv_handle_t *>(&extra_async));
55+ }
4456}
4557
4658NODE_MODULE_CONTEXT_AWARE (NODE_GYP_MODULE_NAME, Initialize)
Original file line number Diff line number Diff line change @@ -6,12 +6,19 @@ const path = require('path');
66const { Worker } = require ( 'worker_threads' ) ;
77const binding = path . resolve ( __dirname , `./build/${ common . buildType } /binding` ) ;
88
9- if ( process . argv [ 2 ] === 'child ' ) {
9+ if ( process . argv [ 2 ] === 'worker ' ) {
1010 new Worker ( `require(${ JSON . stringify ( binding ) } );` , { eval : true } ) ;
11- } else {
11+ return ;
12+ } else if ( process . argv [ 2 ] === 'main-thread' ) {
13+ process . env . addExtraItemToEventLoop = 'yes' ;
14+ require ( binding ) ;
15+ return ;
16+ }
17+
18+ for ( const test of [ 'worker' , 'main-thread' ] ) {
1219 const proc = child_process . spawnSync ( process . execPath , [
1320 __filename ,
14- 'child'
21+ test
1522 ] ) ;
1623 assert . strictEqual ( proc . stderr . toString ( ) , '' ) ;
1724 assert . strictEqual ( proc . stdout . toString ( ) , 'ctor cleanup dtor' ) ;
You can’t perform that action at this time.
0 commit comments