@@ -182,26 +182,43 @@ inline v8::Local<v8::Value> V8LocalValueFromJsValue(napi_value v) {
182
182
183
183
// Adapter for napi_finalize callbacks.
184
184
class 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
+
185
194
protected:
186
195
Finalizer (napi_env env,
187
196
napi_finalize finalize_callback,
188
197
void * finalize_data,
189
- void * finalize_hint)
198
+ void * finalize_hint,
199
+ EnvReferenceMode refmode = kNoEnvReference )
190
200
: _env(env),
191
201
_finalize_callback (finalize_callback),
192
202
_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 ();
194
207
}
195
208
196
- ~Finalizer () = default ;
209
+ ~Finalizer () {
210
+ if (_has_env_reference)
211
+ _env->Unref ();
212
+ }
197
213
198
214
public:
199
215
static Finalizer* New (napi_env env,
200
216
napi_finalize finalize_callback = nullptr ,
201
217
void * finalize_data = nullptr ,
202
- void * finalize_hint = nullptr ) {
218
+ void * finalize_hint = nullptr ,
219
+ EnvReferenceMode refmode = kNoEnvReference ) {
203
220
return new Finalizer (
204
- env, finalize_callback, finalize_data, finalize_hint);
221
+ env, finalize_callback, finalize_data, finalize_hint, refmode );
205
222
}
206
223
207
224
static void Delete (Finalizer* finalizer) {
@@ -214,6 +231,7 @@ class Finalizer {
214
231
void * _finalize_data;
215
232
void * _finalize_hint;
216
233
bool _finalize_ran = false ;
234
+ bool _has_env_reference = false ;
217
235
};
218
236
219
237
class TryCatch : public v8 ::TryCatch {
0 commit comments