@@ -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 { |
|