@@ -186,26 +186,43 @@ inline v8::Local<v8::Value> V8LocalValueFromJsValue(napi_value v) {
186
186
187
187
// Adapter for napi_finalize callbacks.
188
188
class Finalizer {
189
+ public:
190
+ // Some Finalizers are run during shutdown when the napi_env is destroyed,
191
+ // and some need to keep an explicit reference to the napi_env because they
192
+ // are run independently.
193
+ enum EnvReferenceMode {
194
+ kNoEnvReference ,
195
+ kKeepEnvReference
196
+ };
197
+
189
198
protected:
190
199
Finalizer (napi_env env,
191
200
napi_finalize finalize_callback,
192
201
void * finalize_data,
193
- void * finalize_hint)
202
+ void * finalize_hint,
203
+ EnvReferenceMode refmode = kNoEnvReference )
194
204
: _env(env),
195
205
_finalize_callback (finalize_callback),
196
206
_finalize_data(finalize_data),
197
- _finalize_hint(finalize_hint) {
207
+ _finalize_hint(finalize_hint),
208
+ _has_env_reference(refmode == kKeepEnvReference ) {
209
+ if (_has_env_reference)
210
+ _env->Ref ();
198
211
}
199
212
200
- ~Finalizer () = default ;
213
+ ~Finalizer () {
214
+ if (_has_env_reference)
215
+ _env->Unref ();
216
+ }
201
217
202
218
public:
203
219
static Finalizer* New (napi_env env,
204
220
napi_finalize finalize_callback = nullptr ,
205
221
void * finalize_data = nullptr ,
206
- void * finalize_hint = nullptr ) {
222
+ void * finalize_hint = nullptr ,
223
+ EnvReferenceMode refmode = kNoEnvReference ) {
207
224
return new Finalizer (
208
- env, finalize_callback, finalize_data, finalize_hint);
225
+ env, finalize_callback, finalize_data, finalize_hint, refmode );
209
226
}
210
227
211
228
static void Delete (Finalizer* finalizer) {
@@ -218,6 +235,7 @@ class Finalizer {
218
235
void * _finalize_data;
219
236
void * _finalize_hint;
220
237
bool _finalize_ran = false ;
238
+ bool _has_env_reference = false ;
221
239
};
222
240
223
241
class TryCatch : public v8 ::TryCatch {
0 commit comments