@@ -182,26 +182,43 @@ inline v8::Local<v8::Value> V8LocalValueFromJsValue(napi_value v) {
182182
183183// Adapter for napi_finalize callbacks.
184184class Finalizer {
185+ public:
186+ // Some Finalizers are run during shutdown when the napi_env is destroyed,
187+ // and some need to keep an explicit reference to the napi_env because they
188+ // are run independently.
189+ enum EnvReferenceMode {
190+ kNoEnvReference ,
191+ kKeepEnvReference
192+ };
193+
185194 protected:
186195 Finalizer (napi_env env,
187196 napi_finalize finalize_callback,
188197 void * finalize_data,
189- void * finalize_hint)
198+ void * finalize_hint,
199+ EnvReferenceMode refmode = kNoEnvReference )
190200 : _env(env),
191201 _finalize_callback (finalize_callback),
192202 _finalize_data(finalize_data),
193- _finalize_hint(finalize_hint) {
203+ _finalize_hint(finalize_hint),
204+ _has_env_reference(refmode == kKeepEnvReference ) {
205+ if (_has_env_reference)
206+ _env->Ref ();
194207 }
195208
196- ~Finalizer () = default ;
209+ ~Finalizer () {
210+ if (_has_env_reference)
211+ _env->Unref ();
212+ }
197213
198214 public:
199215 static Finalizer* New (napi_env env,
200216 napi_finalize finalize_callback = nullptr ,
201217 void * finalize_data = nullptr ,
202- void * finalize_hint = nullptr ) {
218+ void * finalize_hint = nullptr ,
219+ EnvReferenceMode refmode = kNoEnvReference ) {
203220 return new Finalizer (
204- env, finalize_callback, finalize_data, finalize_hint);
221+ env, finalize_callback, finalize_data, finalize_hint, refmode );
205222 }
206223
207224 static void Delete (Finalizer* finalizer) {
@@ -214,6 +231,7 @@ class Finalizer {
214231 void * _finalize_data;
215232 void * _finalize_hint;
216233 bool _finalize_ran = false ;
234+ bool _has_env_reference = false ;
217235};
218236
219237class TryCatch : public v8 ::TryCatch {
0 commit comments