@@ -186,26 +186,43 @@ inline v8::Local<v8::Value> V8LocalValueFromJsValue(napi_value v) {
186186
187187// Adapter for napi_finalize callbacks.
188188class 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+
189198 protected:
190199 Finalizer (napi_env env,
191200 napi_finalize finalize_callback,
192201 void * finalize_data,
193- void * finalize_hint)
202+ void * finalize_hint,
203+ EnvReferenceMode refmode = kNoEnvReference )
194204 : _env(env),
195205 _finalize_callback (finalize_callback),
196206 _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 ();
198211 }
199212
200- ~Finalizer () = default ;
213+ ~Finalizer () {
214+ if (_has_env_reference)
215+ _env->Unref ();
216+ }
201217
202218 public:
203219 static Finalizer* New (napi_env env,
204220 napi_finalize finalize_callback = nullptr ,
205221 void * finalize_data = nullptr ,
206- void * finalize_hint = nullptr ) {
222+ void * finalize_hint = nullptr ,
223+ EnvReferenceMode refmode = kNoEnvReference ) {
207224 return new Finalizer (
208- env, finalize_callback, finalize_data, finalize_hint);
225+ env, finalize_callback, finalize_data, finalize_hint, refmode );
209226 }
210227
211228 static void Delete (Finalizer* finalizer) {
@@ -218,6 +235,7 @@ class Finalizer {
218235 void * _finalize_data;
219236 void * _finalize_hint;
220237 bool _finalize_ran = false ;
238+ bool _has_env_reference = false ;
221239};
222240
223241class TryCatch : public v8 ::TryCatch {
0 commit comments