node-addon-api 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/napi-inl.h CHANGED
@@ -260,6 +260,45 @@ struct ThreadSafeFinalize {
260
260
  FinalizerDataType* data;
261
261
  Finalizer callback;
262
262
  };
263
+
264
+ template <typename ContextType, typename DataType, typename CallJs, CallJs call>
265
+ typename std::enable_if<call != nullptr>::type static inline CallJsWrapper(
266
+ napi_env env, napi_value jsCallback, void* context, void* data) {
267
+ call(env,
268
+ Function(env, jsCallback),
269
+ static_cast<ContextType*>(context),
270
+ static_cast<DataType*>(data));
271
+ }
272
+
273
+ template <typename ContextType, typename DataType, typename CallJs, CallJs call>
274
+ typename std::enable_if<call == nullptr>::type static inline CallJsWrapper(
275
+ napi_env env, napi_value jsCallback, void* /*context*/, void* /*data*/) {
276
+ if (jsCallback != nullptr) {
277
+ Function(env, jsCallback).Call(0, nullptr);
278
+ }
279
+ }
280
+
281
+ #if NAPI_VERSION > 4
282
+
283
+ template <typename CallbackType, typename TSFN>
284
+ napi_value DefaultCallbackWrapper(napi_env /*env*/, std::nullptr_t /*cb*/) {
285
+ return nullptr;
286
+ }
287
+
288
+ template <typename CallbackType, typename TSFN>
289
+ napi_value DefaultCallbackWrapper(napi_env /*env*/, Napi::Function cb) {
290
+ return cb;
291
+ }
292
+
293
+ #else
294
+ template <typename CallbackType, typename TSFN>
295
+ napi_value DefaultCallbackWrapper(napi_env env, Napi::Function cb) {
296
+ if (cb.IsEmpty()) {
297
+ return TSFN::EmptyFunctionFactory(env);
298
+ }
299
+ return cb;
300
+ }
301
+ #endif // NAPI_VERSION > 4
263
302
  #endif // NAPI_VERSION > 3 && !defined(__wasm32__)
264
303
 
265
304
  template <typename Getter, typename Setter>
@@ -1530,6 +1569,20 @@ inline size_t ArrayBuffer::ByteLength() {
1530
1569
  return length;
1531
1570
  }
1532
1571
 
1572
+ #if NAPI_VERSION >= 7
1573
+ inline bool ArrayBuffer::IsDetached() const {
1574
+ bool detached;
1575
+ napi_status status = napi_is_detached_arraybuffer(_env, _value, &detached);
1576
+ NAPI_THROW_IF_FAILED(_env, status, false);
1577
+ return detached;
1578
+ }
1579
+
1580
+ inline void ArrayBuffer::Detach() {
1581
+ napi_status status = napi_detach_arraybuffer(_env, _value);
1582
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
1583
+ }
1584
+ #endif // NAPI_VERSION >= 7
1585
+
1533
1586
  ////////////////////////////////////////////////////////////////////////////////
1534
1587
  // DataView class
1535
1588
  ////////////////////////////////////////////////////////////////////////////////
@@ -3963,6 +4016,7 @@ inline napi_value ObjectWrap<T>::StaticSetterCallbackWrapper(
3963
4016
 
3964
4017
  template <typename T>
3965
4018
  inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void* data, void* /*hint*/) {
4019
+ HandleScope scope(env);
3966
4020
  T* instance = static_cast<T*>(data);
3967
4021
  instance->Finalize(Napi::Env(env));
3968
4022
  delete instance;
@@ -4338,6 +4392,490 @@ inline void AsyncWorker::OnWorkComplete(Napi::Env /*env*/, napi_status status) {
4338
4392
  }
4339
4393
 
4340
4394
  #if (NAPI_VERSION > 3 && !defined(__wasm32__))
4395
+ ////////////////////////////////////////////////////////////////////////////////
4396
+ // TypedThreadSafeFunction<ContextType,DataType,CallJs> class
4397
+ ////////////////////////////////////////////////////////////////////////////////
4398
+
4399
+ // Starting with NAPI 5, the JavaScript function `func` parameter of
4400
+ // `napi_create_threadsafe_function` is optional.
4401
+ #if NAPI_VERSION > 4
4402
+ // static, with Callback [missing] Resource [missing] Finalizer [missing]
4403
+ template <typename ContextType,
4404
+ typename DataType,
4405
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4406
+ template <typename ResourceString>
4407
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4408
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4409
+ napi_env env,
4410
+ ResourceString resourceName,
4411
+ size_t maxQueueSize,
4412
+ size_t initialThreadCount,
4413
+ ContextType* context) {
4414
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4415
+
4416
+ napi_status status =
4417
+ napi_create_threadsafe_function(env,
4418
+ nullptr,
4419
+ nullptr,
4420
+ String::From(env, resourceName),
4421
+ maxQueueSize,
4422
+ initialThreadCount,
4423
+ nullptr,
4424
+ nullptr,
4425
+ context,
4426
+ CallJsInternal,
4427
+ &tsfn._tsfn);
4428
+ if (status != napi_ok) {
4429
+ NAPI_THROW_IF_FAILED(
4430
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
4431
+ }
4432
+
4433
+ return tsfn;
4434
+ }
4435
+
4436
+ // static, with Callback [missing] Resource [passed] Finalizer [missing]
4437
+ template <typename ContextType,
4438
+ typename DataType,
4439
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4440
+ template <typename ResourceString>
4441
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4442
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4443
+ napi_env env,
4444
+ const Object& resource,
4445
+ ResourceString resourceName,
4446
+ size_t maxQueueSize,
4447
+ size_t initialThreadCount,
4448
+ ContextType* context) {
4449
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4450
+
4451
+ napi_status status =
4452
+ napi_create_threadsafe_function(env,
4453
+ nullptr,
4454
+ resource,
4455
+ String::From(env, resourceName),
4456
+ maxQueueSize,
4457
+ initialThreadCount,
4458
+ nullptr,
4459
+ nullptr,
4460
+ context,
4461
+ CallJsInternal,
4462
+ &tsfn._tsfn);
4463
+ if (status != napi_ok) {
4464
+ NAPI_THROW_IF_FAILED(
4465
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
4466
+ }
4467
+
4468
+ return tsfn;
4469
+ }
4470
+
4471
+ // static, with Callback [missing] Resource [missing] Finalizer [passed]
4472
+ template <typename ContextType,
4473
+ typename DataType,
4474
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4475
+ template <typename ResourceString,
4476
+ typename Finalizer,
4477
+ typename FinalizerDataType>
4478
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4479
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4480
+ napi_env env,
4481
+ ResourceString resourceName,
4482
+ size_t maxQueueSize,
4483
+ size_t initialThreadCount,
4484
+ ContextType* context,
4485
+ Finalizer finalizeCallback,
4486
+ FinalizerDataType* data) {
4487
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4488
+
4489
+ auto* finalizeData = new details::
4490
+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
4491
+ {data, finalizeCallback});
4492
+ napi_status status = napi_create_threadsafe_function(
4493
+ env,
4494
+ nullptr,
4495
+ nullptr,
4496
+ String::From(env, resourceName),
4497
+ maxQueueSize,
4498
+ initialThreadCount,
4499
+ finalizeData,
4500
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
4501
+ FinalizeFinalizeWrapperWithDataAndContext,
4502
+ context,
4503
+ CallJsInternal,
4504
+ &tsfn._tsfn);
4505
+ if (status != napi_ok) {
4506
+ delete finalizeData;
4507
+ NAPI_THROW_IF_FAILED(
4508
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
4509
+ }
4510
+
4511
+ return tsfn;
4512
+ }
4513
+
4514
+ // static, with Callback [missing] Resource [passed] Finalizer [passed]
4515
+ template <typename ContextType,
4516
+ typename DataType,
4517
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4518
+ template <typename ResourceString,
4519
+ typename Finalizer,
4520
+ typename FinalizerDataType>
4521
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4522
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4523
+ napi_env env,
4524
+ const Object& resource,
4525
+ ResourceString resourceName,
4526
+ size_t maxQueueSize,
4527
+ size_t initialThreadCount,
4528
+ ContextType* context,
4529
+ Finalizer finalizeCallback,
4530
+ FinalizerDataType* data) {
4531
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4532
+
4533
+ auto* finalizeData = new details::
4534
+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
4535
+ {data, finalizeCallback});
4536
+ napi_status status = napi_create_threadsafe_function(
4537
+ env,
4538
+ nullptr,
4539
+ resource,
4540
+ String::From(env, resourceName),
4541
+ maxQueueSize,
4542
+ initialThreadCount,
4543
+ finalizeData,
4544
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
4545
+ FinalizeFinalizeWrapperWithDataAndContext,
4546
+ context,
4547
+ CallJsInternal,
4548
+ &tsfn._tsfn);
4549
+ if (status != napi_ok) {
4550
+ delete finalizeData;
4551
+ NAPI_THROW_IF_FAILED(
4552
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
4553
+ }
4554
+
4555
+ return tsfn;
4556
+ }
4557
+ #endif
4558
+
4559
+ // static, with Callback [passed] Resource [missing] Finalizer [missing]
4560
+ template <typename ContextType,
4561
+ typename DataType,
4562
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4563
+ template <typename ResourceString>
4564
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4565
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4566
+ napi_env env,
4567
+ const Function& callback,
4568
+ ResourceString resourceName,
4569
+ size_t maxQueueSize,
4570
+ size_t initialThreadCount,
4571
+ ContextType* context) {
4572
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4573
+
4574
+ napi_status status =
4575
+ napi_create_threadsafe_function(env,
4576
+ callback,
4577
+ nullptr,
4578
+ String::From(env, resourceName),
4579
+ maxQueueSize,
4580
+ initialThreadCount,
4581
+ nullptr,
4582
+ nullptr,
4583
+ context,
4584
+ CallJsInternal,
4585
+ &tsfn._tsfn);
4586
+ if (status != napi_ok) {
4587
+ NAPI_THROW_IF_FAILED(
4588
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
4589
+ }
4590
+
4591
+ return tsfn;
4592
+ }
4593
+
4594
+ // static, with Callback [passed] Resource [passed] Finalizer [missing]
4595
+ template <typename ContextType,
4596
+ typename DataType,
4597
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4598
+ template <typename ResourceString>
4599
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4600
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4601
+ napi_env env,
4602
+ const Function& callback,
4603
+ const Object& resource,
4604
+ ResourceString resourceName,
4605
+ size_t maxQueueSize,
4606
+ size_t initialThreadCount,
4607
+ ContextType* context) {
4608
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4609
+
4610
+ napi_status status =
4611
+ napi_create_threadsafe_function(env,
4612
+ callback,
4613
+ resource,
4614
+ String::From(env, resourceName),
4615
+ maxQueueSize,
4616
+ initialThreadCount,
4617
+ nullptr,
4618
+ nullptr,
4619
+ context,
4620
+ CallJsInternal,
4621
+ &tsfn._tsfn);
4622
+ if (status != napi_ok) {
4623
+ NAPI_THROW_IF_FAILED(
4624
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
4625
+ }
4626
+
4627
+ return tsfn;
4628
+ }
4629
+
4630
+ // static, with Callback [passed] Resource [missing] Finalizer [passed]
4631
+ template <typename ContextType,
4632
+ typename DataType,
4633
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4634
+ template <typename ResourceString,
4635
+ typename Finalizer,
4636
+ typename FinalizerDataType>
4637
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4638
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4639
+ napi_env env,
4640
+ const Function& callback,
4641
+ ResourceString resourceName,
4642
+ size_t maxQueueSize,
4643
+ size_t initialThreadCount,
4644
+ ContextType* context,
4645
+ Finalizer finalizeCallback,
4646
+ FinalizerDataType* data) {
4647
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4648
+
4649
+ auto* finalizeData = new details::
4650
+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
4651
+ {data, finalizeCallback});
4652
+ napi_status status = napi_create_threadsafe_function(
4653
+ env,
4654
+ callback,
4655
+ nullptr,
4656
+ String::From(env, resourceName),
4657
+ maxQueueSize,
4658
+ initialThreadCount,
4659
+ finalizeData,
4660
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
4661
+ FinalizeFinalizeWrapperWithDataAndContext,
4662
+ context,
4663
+ CallJsInternal,
4664
+ &tsfn._tsfn);
4665
+ if (status != napi_ok) {
4666
+ delete finalizeData;
4667
+ NAPI_THROW_IF_FAILED(
4668
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
4669
+ }
4670
+
4671
+ return tsfn;
4672
+ }
4673
+
4674
+ // static, with: Callback [passed] Resource [passed] Finalizer [passed]
4675
+ template <typename ContextType,
4676
+ typename DataType,
4677
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4678
+ template <typename CallbackType,
4679
+ typename ResourceString,
4680
+ typename Finalizer,
4681
+ typename FinalizerDataType>
4682
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4683
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4684
+ napi_env env,
4685
+ CallbackType callback,
4686
+ const Object& resource,
4687
+ ResourceString resourceName,
4688
+ size_t maxQueueSize,
4689
+ size_t initialThreadCount,
4690
+ ContextType* context,
4691
+ Finalizer finalizeCallback,
4692
+ FinalizerDataType* data) {
4693
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4694
+
4695
+ auto* finalizeData = new details::
4696
+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
4697
+ {data, finalizeCallback});
4698
+ napi_status status = napi_create_threadsafe_function(
4699
+ env,
4700
+ details::DefaultCallbackWrapper<
4701
+ CallbackType,
4702
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>>(env,
4703
+ callback),
4704
+ resource,
4705
+ String::From(env, resourceName),
4706
+ maxQueueSize,
4707
+ initialThreadCount,
4708
+ finalizeData,
4709
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
4710
+ FinalizeFinalizeWrapperWithDataAndContext,
4711
+ context,
4712
+ CallJsInternal,
4713
+ &tsfn._tsfn);
4714
+ if (status != napi_ok) {
4715
+ delete finalizeData;
4716
+ NAPI_THROW_IF_FAILED(
4717
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
4718
+ }
4719
+
4720
+ return tsfn;
4721
+ }
4722
+
4723
+ template <typename ContextType,
4724
+ typename DataType,
4725
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4726
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
4727
+ TypedThreadSafeFunction()
4728
+ : _tsfn() {}
4729
+
4730
+ template <typename ContextType,
4731
+ typename DataType,
4732
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4733
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
4734
+ TypedThreadSafeFunction(napi_threadsafe_function tsfn)
4735
+ : _tsfn(tsfn) {}
4736
+
4737
+ template <typename ContextType,
4738
+ typename DataType,
4739
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4740
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
4741
+ operator napi_threadsafe_function() const {
4742
+ return _tsfn;
4743
+ }
4744
+
4745
+ template <typename ContextType,
4746
+ typename DataType,
4747
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4748
+ inline napi_status
4749
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::BlockingCall(
4750
+ DataType* data) const {
4751
+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_blocking);
4752
+ }
4753
+
4754
+ template <typename ContextType,
4755
+ typename DataType,
4756
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4757
+ inline napi_status
4758
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::NonBlockingCall(
4759
+ DataType* data) const {
4760
+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_nonblocking);
4761
+ }
4762
+
4763
+ template <typename ContextType,
4764
+ typename DataType,
4765
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4766
+ inline void TypedThreadSafeFunction<ContextType, DataType, CallJs>::Ref(
4767
+ napi_env env) const {
4768
+ if (_tsfn != nullptr) {
4769
+ napi_status status = napi_ref_threadsafe_function(env, _tsfn);
4770
+ NAPI_THROW_IF_FAILED_VOID(env, status);
4771
+ }
4772
+ }
4773
+
4774
+ template <typename ContextType,
4775
+ typename DataType,
4776
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4777
+ inline void TypedThreadSafeFunction<ContextType, DataType, CallJs>::Unref(
4778
+ napi_env env) const {
4779
+ if (_tsfn != nullptr) {
4780
+ napi_status status = napi_unref_threadsafe_function(env, _tsfn);
4781
+ NAPI_THROW_IF_FAILED_VOID(env, status);
4782
+ }
4783
+ }
4784
+
4785
+ template <typename ContextType,
4786
+ typename DataType,
4787
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4788
+ inline napi_status
4789
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::Acquire() const {
4790
+ return napi_acquire_threadsafe_function(_tsfn);
4791
+ }
4792
+
4793
+ template <typename ContextType,
4794
+ typename DataType,
4795
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4796
+ inline napi_status
4797
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::Release() {
4798
+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_release);
4799
+ }
4800
+
4801
+ template <typename ContextType,
4802
+ typename DataType,
4803
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4804
+ inline napi_status
4805
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::Abort() {
4806
+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_abort);
4807
+ }
4808
+
4809
+ template <typename ContextType,
4810
+ typename DataType,
4811
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4812
+ inline ContextType*
4813
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::GetContext() const {
4814
+ void* context;
4815
+ napi_status status = napi_get_threadsafe_function_context(_tsfn, &context);
4816
+ NAPI_FATAL_IF_FAILED(status,
4817
+ "TypedThreadSafeFunction::GetContext",
4818
+ "napi_get_threadsafe_function_context");
4819
+ return static_cast<ContextType*>(context);
4820
+ }
4821
+
4822
+ // static
4823
+ template <typename ContextType,
4824
+ typename DataType,
4825
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4826
+ void TypedThreadSafeFunction<ContextType, DataType, CallJs>::CallJsInternal(
4827
+ napi_env env, napi_value jsCallback, void* context, void* data) {
4828
+ details::CallJsWrapper<ContextType, DataType, decltype(CallJs), CallJs>(
4829
+ env, jsCallback, context, data);
4830
+ }
4831
+
4832
+ #if NAPI_VERSION == 4
4833
+ // static
4834
+ template <typename ContextType,
4835
+ typename DataType,
4836
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4837
+ Napi::Function
4838
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::EmptyFunctionFactory(
4839
+ Napi::Env env) {
4840
+ return Napi::Function::New(env, [](const CallbackInfo& cb) {});
4841
+ }
4842
+
4843
+ // static
4844
+ template <typename ContextType,
4845
+ typename DataType,
4846
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4847
+ Napi::Function
4848
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::FunctionOrEmpty(
4849
+ Napi::Env env, Napi::Function& callback) {
4850
+ if (callback.IsEmpty()) {
4851
+ return EmptyFunctionFactory(env);
4852
+ }
4853
+ return callback;
4854
+ }
4855
+
4856
+ #else
4857
+ // static
4858
+ template <typename ContextType,
4859
+ typename DataType,
4860
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4861
+ std::nullptr_t
4862
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::EmptyFunctionFactory(
4863
+ Napi::Env /*env*/) {
4864
+ return nullptr;
4865
+ }
4866
+
4867
+ // static
4868
+ template <typename ContextType,
4869
+ typename DataType,
4870
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4871
+ Napi::Function
4872
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::FunctionOrEmpty(
4873
+ Napi::Env /*env*/, Napi::Function& callback) {
4874
+ return callback;
4875
+ }
4876
+
4877
+ #endif
4878
+
4341
4879
  ////////////////////////////////////////////////////////////////////////////////
4342
4880
  // ThreadSafeFunction class
4343
4881
  ////////////////////////////////////////////////////////////////////////////////
@@ -4730,6 +5268,7 @@ inline void AsyncProgressWorkerBase<DataType>::OnAsyncWorkProgress(Napi::Env /*
4730
5268
  void* data) {
4731
5269
  ThreadSafeData* tsd = static_cast<ThreadSafeData*>(data);
4732
5270
  tsd->asyncprogressworker()->OnWorkProgress(tsd->data());
5271
+ delete tsd;
4733
5272
  }
4734
5273
 
4735
5274
  template <typename DataType>
@@ -4851,6 +5390,17 @@ inline void AsyncProgressWorker<T>::OnWorkProgress(void*) {
4851
5390
  this->_asyncsize = 0;
4852
5391
  }
4853
5392
 
5393
+ /**
5394
+ * The callback of ThreadSafeFunction is not been invoked immediately on the
5395
+ * callback of uv_async_t (uv io poll), rather the callback of TSFN is
5396
+ * invoked on the right next uv idle callback. There are chances that during
5397
+ * the deferring the signal of uv_async_t is been sent again, i.e. potential
5398
+ * not coalesced two calls of the TSFN callback.
5399
+ */
5400
+ if (data == nullptr) {
5401
+ return;
5402
+ }
5403
+
4854
5404
  this->OnProgress(data, size);
4855
5405
  delete[] data;
4856
5406
  }