@@ -103,7 +103,6 @@ using v8::Value;
103
103
// Globals per process
104
104
static node_module* modlist_internal;
105
105
static node_module* modlist_linked;
106
- static node_module* modlist_addon;
107
106
static uv_once_t init_modpending_once = UV_ONCE_INIT;
108
107
static uv_key_t thread_local_modpending;
109
108
@@ -129,6 +128,48 @@ extern "C" void node_module_register(void* m) {
129
128
130
129
namespace binding {
131
130
131
+ static struct global_handle_map_t {
132
+ public:
133
+ void set (void * handle, node_module* mod) {
134
+ CHECK_NE (handle, nullptr );
135
+ Mutex::ScopedLock lock (mutex_);
136
+
137
+ map_[handle] = Entry { 1 , mod };
138
+ }
139
+
140
+ node_module* get_and_increase_refcount (void * handle) {
141
+ CHECK_NE (handle, nullptr );
142
+ Mutex::ScopedLock lock (mutex_);
143
+
144
+ auto it = map_.find (handle);
145
+ if (it == map_.end ()) return nullptr ;
146
+ it->second .refcount ++;
147
+ return it->second .module ;
148
+ }
149
+
150
+ void erase (void * handle) {
151
+ CHECK_NE (handle, nullptr );
152
+ Mutex::ScopedLock lock (mutex_);
153
+
154
+ auto it = map_.find (handle);
155
+ if (it == map_.end ()) return ;
156
+ CHECK_GE (it->second .refcount , 1 );
157
+ if (--it->second .refcount == 0 ) {
158
+ if (it->second .module ->nm_flags & NM_F_DELETEME)
159
+ delete it->second .module ;
160
+ map_.erase (handle);
161
+ }
162
+ }
163
+
164
+ private:
165
+ Mutex mutex_;
166
+ struct Entry {
167
+ unsigned int refcount;
168
+ node_module* module;
169
+ };
170
+ std::unordered_map<void *, Entry> map_;
171
+ } global_handle_map;
172
+
132
173
DLib::DLib (const char * filename, int flags)
133
174
: filename_(filename), flags_(flags), handle_(nullptr ) {}
134
175
@@ -142,6 +183,7 @@ bool DLib::Open() {
142
183
143
184
void DLib::Close () {
144
185
if (handle_ == nullptr ) return ;
186
+ global_handle_map.erase (handle_);
145
187
dlclose (handle_);
146
188
handle_ = nullptr ;
147
189
}
@@ -233,7 +275,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
233
275
// Objects containing v14 or later modules will have registered themselves
234
276
// on the pending list. Activate all of them now. At present, only one
235
277
// module per object is supported.
236
- node_module* const mp =
278
+ node_module* mp =
237
279
static_cast <node_module*>(uv_key_get (&thread_local_modpending));
238
280
uv_key_set (&thread_local_modpending, nullptr );
239
281
@@ -250,17 +292,24 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
250
292
return false ;
251
293
}
252
294
253
- if (mp == nullptr ) {
295
+ if (mp != nullptr ) {
296
+ mp->nm_dso_handle = dlib->handle_ ;
297
+ global_handle_map.set (dlib->handle_ , mp);
298
+ } else {
254
299
if (auto callback = GetInitializerCallback (dlib)) {
255
300
callback (exports, module, context);
301
+ return true ;
256
302
} else if (auto napi_callback = GetNapiInitializerCallback (dlib)) {
257
303
napi_module_register_by_symbol (exports, module, context, napi_callback);
304
+ return true ;
258
305
} else {
259
- dlib->Close ();
260
- env->ThrowError (" Module did not self-register." );
261
- return false ;
306
+ mp = global_handle_map.get_and_increase_refcount (dlib->handle_ );
307
+ if (mp == nullptr || mp->nm_context_register_func == nullptr ) {
308
+ dlib->Close ();
309
+ env->ThrowError (" Module did not self-register." );
310
+ return false ;
311
+ }
262
312
}
263
- return true ;
264
313
}
265
314
266
315
// -1 is used for N-API modules
@@ -293,10 +342,6 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
293
342
}
294
343
CHECK_EQ (mp->nm_flags & NM_F_BUILTIN, 0 );
295
344
296
- mp->nm_dso_handle = dlib->handle_ ;
297
- mp->nm_link = modlist_addon;
298
- modlist_addon = mp;
299
-
300
345
if (mp->nm_context_register_func != nullptr ) {
301
346
mp->nm_context_register_func (exports, module, context, mp->nm_priv );
302
347
} else if (mp->nm_register_func != nullptr ) {
0 commit comments