profile
viewpoint
Jinho Bang romandev Samsung Electronics Suwon, Korea https://romandev.github.io Open Web Platform Developer

issue commentw3c/payment-handler

Does PaymentManager need to be exposed to Worker scope?

@rsolomakhin, Yeah, but if we want to expose the PaymentManager in ServiceWorker(not pure Worker) and Window, then we can change it as follows: [Exposed=(Window, ServiceWorker)]

That being said, I believe we should keep it for consistency according to my earlier comment if there is no special reason(e.g. security risk) not to expose to Worker.

danyao

comment created time in 20 days

startedboost-experimental/di

started time in a month

issue commentw3c/payment-handler

Does PaymentManager need to be exposed to Worker scope?

Hi, @danyao

I left inline comments :)

The PaymentManager interface currently has [Exposed=(Window,Worker)] in the spec. I wonder if the Worker scope is necessary.

Do you have any special reasons to introduce the restriction? For example, requestPermission() contained a permission UI prompt. As you know, the UI should be invoked on main thread. So the [Exposed=Window] restriction was added to requestPermission().

On the other hand, the PaymentManager is exposed as an attribute to extended ServiceWorkerRegistration. Today, we can access the ServiceWorkerRegistration in Worker scope(including ServiceWorker) as well as Window scope[1]. Therefore, it is reasonable that the attribute is exposed to the equivalent scope as ServiceWorkerRegistration if there is no special reasons.

Currently PaymentManager is only ever used through the service worker registration's paymentManager instance. Chrome's current implementation doesn't use [Exposed], which defaults to Window.

It might be a Chrome bug. Looking into the history at Chromium[2], when I implemented this feature first(2016), there was no "Exposed" extended attribute in the spec. After that, while implementing/standardizing requestPermission(), we have added a restriction that expose the method to Window scope only because of a permission UI prompt. And I realized that we missed Exposed extended attribute for PaymentManager. So, I added it as well. (2017) However, I forgot to reflect the spec change to Chromium/Blink and the PaymentHandler was just shipped without fixing the change in Chrome.

Thank you.

[1] https://w3c.github.io/ServiceWorker/#serviceworkerregistration-interface [2] https://chromium.googlesource.com/chromium/src/+/60a84ca8de6308a26f8500600ad8ba7c1ce2a41c/third_party/WebKit/Source/modules/payments/PaymentAppManager.idl

danyao

comment created time in a month

startedadblockplus/adblockpluscore

started time in a month

pull request commentnodejs/node-addon-api

Implement ThreadSafeFunction class

FYI, I got rid of std::make_unique from latest patch because the make_unique() is C++ 14 feature..

romandev

comment created time in 2 months

push eventromandev/node-addon-api

Jinho Bang

commit sha d534bdf6938cdfbaef8da791ea0beaa813245e67

Implement ThreadSafeFunction class This PR is implementing ThreadSafeFunction class wraps napi_threadsafe_function features. FYI, the test files that included in this PR have come from Node.js repo[1]. They've been rewritten based on C++ and node-addon-api. Fixes #312. [1] https://github.com/nodejs/node/tree/master/test/node-api/test_threadsafe_function

view details

push time in 2 months

pull request commentnodejs/node-addon-api

Implement ThreadSafeFunction class

@romandev can you please move the test over to std::thread?

@gabrielschulhof Done. Thanks.

romandev

comment created time in 2 months

push eventromandev/node-addon-api

Jinho Bang

commit sha 19c115d3edbd39ef25341891716cad77d88f1fac

Implement ThreadSafeFunction class This PR is implementing ThreadSafeFunction class wraps napi_threadsafe_function features. FYI, the test files that included in this PR have come from Node.js repo[1]. They've been rewritten based on C++ and node-addon-api. Fixes #312. [1] https://github.com/nodejs/node/tree/master/test/node-api/test_threadsafe_function

view details

push time in 2 months

startedline/armeria

started time in 2 months

startedNavidZ/input-for-workers

started time in 2 months

pull request commentw3c/test-results

Update Samsung Internet 9.4 implementation report

@ianbjacobs PTAL (Sorry for delayed update.)

romandev

comment created time in 2 months

push eventromandev/w3c-test-results

Jinho Bang

commit sha bbdc6fd15d6ad9626339ae61be1ef1c45a686c32

Update Samsung Internet 9.4 implementation report (#197)

view details

aestes

commit sha cfb079d71fb3a73ca6c43466d996336f0ed604b5

Added Payment Request implementation report for Safari 13 on macOS 10.15 beta. (#198) * payment-request/SF13.json: Added.

view details

Ian Jacobs

commit sha 9417cc83116697a9c3a50e50d6abab63cf6a49ea

Addition of SF13 from Andy

view details

Ian Jacobs

commit sha 04a8dcaf1f4c0e6920762a7d500585d43f7bf731

in favor of SF13.json

view details

Ian Jacobs

commit sha d396e6ec3f50542d2e3d220cf4b8e12ee06edd7d

remove SF12

view details

Danyao Wang

commit sha 7be9138cb10d5d77da575925dddc476af6be9246

Replace CH76 with CH77 results (#199)

view details

Ian Jacobs

commit sha 5d8d9f0afa9253dfcd5c80427f94be74e89224b7

updated for CH77

view details

Jinho Bang

commit sha 5b91db8791a3ace39ea828eb4dcc498d2f656e3b

Update Samsung Internet 9.4 implementation report

view details

push time in 2 months

startedromandev/wpt

started time in 2 months

fork romandev/wpt

Test suites for Web platform specs — including WHATWG, W3C, and others

http://irc.w3.org/?channels=testing

fork in 2 months

pull request commentnodejs/node-addon-api

Implement ThreadSafeFunction class

@gabrielschulhof, In fact, I already did that here: https://github.com/nodejs/node-addon-api/pull/442/files#diff-f546e4cc35b454813e5264fe9c9e6fc8R3898

However, I think we still need a way to reset the ThreadSafeFunction to empty in ThreadSafeFinalizeCallback if the ThreadSafeFunction is aborted or released.

For example, in the current test, declare ThreadSafeFunction as a static global variable, and assign a new ThreadSafeFunction whenever StartThreadInternal is called. If it's non-empty at this time, it would throw an exception. However, if it's empty (by ThreadSafeFinalizeCallback), we can re-assign a new object again.

If there was no such logic, we would have to have a static ThreadSafeFunction array to create a new ThreadSafeFunction whenever StartThreadInternal is called. (because there would be no way to re-assign a new object) Or, we might need to make a wrapper object for ThreadSafeFunction on heap to maintain creating/destroying the object.

romandev

comment created time in 2 months

pull request commentnodejs/node-addon-api

Implement ThreadSafeFunction class

@fholzer, Thank you for finding the bug :) I addressed the bug in latest patch. Could you please check it again?

@gabrielschulhof, As I mentioned in my previous comment[1], this code is necessary to reset the internal tsfn_ value of ThreadSafeFunction automatically. [1] https://github.com/nodejs/node-addon-api/pull/442#discussion_r285868822

Otherwise, ThreadSafeFunction wrapper should provide Reset() to reset the internal value and then users should explicitly call the method in finalize callback.

The problem is caused that ThreadSafeFunction is already destroyed but finalize callback tries to write nullptr value to the internal value of destroyed TSFN. I used raw pointer in the FinalizeCallback, so, there was no way to detect whether TSFN is already destroyed. So, I used std::weak_ptr instead of raw pointer in latest patch set. It looks to work well.

romandev

comment created time in 2 months

push eventromandev/node-addon-api

Jinho Bang

commit sha 86223cf417822117dec368db5ac4244a7bd49afd

Implement ThreadSafeFunction class This PR is implementing ThreadSafeFunction class wraps napi_threadsafe_function features. FYI, the test files that included in this PR have come from Node.js repo[1]. They've been rewritten based on C++ and node-addon-api. Fixes #312. [1] https://github.com/nodejs/node/tree/master/test/node-api/test_threadsafe_function

view details

push time in 2 months

push eventromandev/node-addon-api

Hitesh Kanwathirtha

commit sha a3b4d99c456ddedb4defec7652033dae1184926e

doc: Add contribution philosophy doc

view details

Alba Mendez

commit sha 3ad5dfc7d9c4ae4b6a1f2cd9ba0eb15dc885b869

Fix link PR-URL: https://github.com/nodejs/node-addon-api/pull/481 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: NickNaso <nicoladelgobbo@gmail.com>

view details

NickNaso

commit sha e1cf9a35a1b6edc404c1b465ec94f8a821641059

Use `Value::IsEmpty` to check for empty value PR-URL: https://github.com/nodejs/node-addon-api/pull/478 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>

view details

Nicola Del Gobbo

commit sha aaea55eda990c42d181a67084f7a17a3f9e56497

Little fix on code example PR-URL: https://github.com/nodejs/node-addon-api/pull/470 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Hitesh Kanwathirtha <digitalinfinity@gmail.com>

view details

Tux3

commit sha f633fbd95d233adc8f030954651a76ec4c8d07f9

string.md: Document existing New(env, value, length) APIs PR-URL: https://github.com/nodejs/node-addon-api/pull/486 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: NickNaso <nicoladelgobbo@gmail.com>

view details

Gabriel Schulhof

commit sha 3b6b9eb88aaef2a971908aa1daf56b00276f94e2

AsyncWorker: introduce Destroy() method `AsyncWorker` contained the assumption that instances of its subclasses were allocated using `new`, because it unconditionally destroyed instances using `delete`. This change replaces the call to `delete` with a call to a protected instance method `Destroy()`, which can be overridden by subclasses. This ensures that users can employ their own allocators when creating `AsyncWorker` subclass instances because they can override the `Destroy()` method to use their deallocator of choice. Re: https://github.com/nodejs/node-addon-api/issues/231#issuecomment-480928142 PR-URL: https://github.com/nodejs/node-addon-api/pull/488 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>

view details

Michael Dawson

commit sha ab7d8fcc48f5727961a0f09442d6ae4c5f9b5a17

src: fix objectwrap test case Refs: https://github.com/nodejs/node-addon-api/issues/485 The test case was relyingon the ordering of "for in" which is not guarranteed as per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in Update the testcase to check in an way that does not depend on ordering. PR-URL: https://github.com/nodejs/node-addon-api/pull/495 Refs: https://github.com/nodejs/node-addon-api/issues/485 Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: NickNaso <nicoladelgobbo@gmail.com>

view details

Jinho Bang

commit sha 30b1087ef5602fd275262f4cf48791d369b990ed

Implement ThreadSafeFunction class This PR is implementing ThreadSafeFunction class wraps napi_threadsafe_function features. FYI, the test files that included in this PR have come from Node.js repo[1]. They've been rewritten based on C++ and node-addon-api. Fixes #312. [1] https://github.com/nodejs/node/tree/master/test/node-api/test_threadsafe_function

view details

push time in 2 months

Pull request review commentnodejs/node-addon-api

Implement ThreadSafeFunction class

 namespace Napi {     bool _suppress_destruct;   }; +  class ThreadSafeFunction {+  public:+    // Default set+    template <typename ResourceString>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount);++    // Default set + Context+    template <typename ResourceString, typename ContextType>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context);++    // Default set + Finalizer+    template <typename ResourceString, typename Finalizer>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback);++    // Default set + Finalizer + Data+    template <typename ResourceString, typename Finalizer,+              typename FinalizerDataType>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data);++    // Default set + Context + Finalizer+    template <typename ResourceString, typename ContextType, typename Finalizer>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback);++    // Default set + Context + Finalizer + Data+    template <typename ResourceString, typename ContextType,+              typename Finalizer, typename FinalizerDataType>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data);++    // Default set + Resource+    template <typename ResourceString>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount);++    // Default set + Resource + Context+    template <typename ResourceString, typename ContextType>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context);++    // Default set + Resource + Finalizer+    template <typename ResourceString, typename Finalizer>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback);++    // Default set + Resource + Finalizer + Data+    template <typename ResourceString, typename Finalizer,+              typename FinalizerDataType>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data);++    // Default set + Resource + Context + Finalizer+    template <typename ResourceString, typename ContextType, typename Finalizer>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback);++    // Default set + Resource + Context + Finalizer + Data+    template <typename ResourceString, typename ContextType,+              typename Finalizer, typename FinalizerDataType>+    static ThreadSafeFunction New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data);

Could you let me know more details about the consistency you mentioned? I'm not sure but the most of New() methods are already using napi_env instead of Napi::Env.

FYI, please see the following grep result.

$ grep -Enr "New\((Napi::Env|Env|napi_env)" napi.h

693:    static External New(napi_env env, T* data);
697:    static External New(napi_env env,
702:    static External New(napi_env env,
715:    static Array New(napi_env env);
716:    static Array New(napi_env env, size_t length);
908:    static DataView New(napi_env env,
910:    static DataView New(napi_env env,
913:    static DataView New(napi_env env,
961:    static Function New(napi_env env,
968:    static Function New(napi_env env,
1005:      static Deferred New(napi_env env);
1026:    static Buffer<T> New(napi_env env, size_t length);
1027:    static Buffer<T> New(napi_env env, T* data, size_t length);
1031:    static Buffer<T> New(napi_env env, T* data,
1036:    static Buffer<T> New(napi_env env, T* data,
1285:    static Error New(napi_env env);
1286:    static Error New(napi_env env, const char* message);
1287:    static Error New(napi_env env, const std::string& message);
1312:    static TError New(napi_env env,
1324:    static TypeError New(napi_env env, const char* message);
1325:    static TypeError New(napi_env env, const std::string& message);
1333:    static RangeError New(napi_env env, const char* message);
1334:    static RangeError New(napi_env env, const std::string& message);
1829:    static ThreadSafeFunction New(napi_env env,
1837:    static ThreadSafeFunction New(napi_env env,
1846:    static ThreadSafeFunction New(napi_env env,
1856:    static ThreadSafeFunction New(napi_env env,
1866:    static ThreadSafeFunction New(napi_env env,
1877:    static ThreadSafeFunction New(napi_env env,
1888:    static ThreadSafeFunction New(napi_env env,
1897:    static ThreadSafeFunction New(napi_env env,
1907:    static ThreadSafeF1897:    static ThreadSafeFunction New(napi_env env,
1907:    static ThreadSafeFunction New(napi_env env,
1918:    static ThreadSafeFunction New(napi_env env,
1929:    static ThreadSafeFunction New(napi_env env,
1941:    static ThreadSafeFunction New(napi_env env,
2003:    static ThreadSafeFunction New(napi_env env,
romandev

comment created time in 2 months

Pull request review commentnodejs/node-addon-api

Implement ThreadSafeFunction class

 namespace Napi {     bool _suppress_destruct;   }; +  class ThreadSafeFunction {+  public:+    // Default set

What does "Default set" mean?

Unmeaningful. There are many overloaded methods. So, I was so confusing. To clarify it during development, it's just used for my convenience.

Also, we should have comments that split the API into functions which can only be called from the main thread, and those that are thread-safe.

Done

romandev

comment created time in 2 months

Pull request review commentnodejs/node-addon-api

Implement ThreadSafeFunction class

 inline void AsyncWorker::OnWorkComplete(   } } +////////////////////////////////////////////////////////////////////////////////+// ThreadSafeFunction class+////////////////////////////////////////////////////////////////////////////////++// static+template <typename ResourceString>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount);+}++// static+template <typename ResourceString, typename ContextType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context);+}++// static+template <typename ResourceString, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, finalizeCallback);+}++// static+template <typename ResourceString, typename Finalizer,+          typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, finalizeCallback, data);+}++// static+template <typename ResourceString, typename ContextType, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback);+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback, data);+}++// static+template <typename ResourceString>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */);+}++// static+template <typename ResourceString, typename ContextType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context,+             [](Env, ContextType*) {} /* empty finalizer */);+}++// static+template <typename ResourceString, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */,+             finalizeCallback, static_cast<void*>(nullptr) /* data */,+             details::ThreadSafeFinalize<void, Finalizer>::Wrapper);+}++// static+template <typename ResourceString, typename Finalizer,+          typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */,+             finalizeCallback, data,+             details::ThreadSafeFinalize<+                 void, Finalizer, FinalizerDataType>::WrapperWithData);+}++// static+template <typename ResourceString, typename ContextType, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback,+             static_cast<void*>(nullptr) /* data */,+             details::ThreadSafeFinalize<+                 ContextType, Finalizer>::WrapperWithContext);+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  const Object& resource,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback, data,+             details::ThreadSafeFinalize<ContextType, Finalizer,+                 FinalizerDataType>::WrapperWithDataAndContext);+}++inline ThreadSafeFunction::ThreadSafeFunction()+  : _tsfn(std::make_unique<napi_threadsafe_function>(nullptr)) {+}++inline ThreadSafeFunction::ThreadSafeFunction(+    napi_threadsafe_function tsfn)+  : _tsfn(std::make_unique<napi_threadsafe_function>(tsfn)) {+}++inline ThreadSafeFunction::ThreadSafeFunction(ThreadSafeFunction&& other)+  : _tsfn(std::move(other._tsfn)) {+  other._tsfn.reset();+}++inline ThreadSafeFunction& ThreadSafeFunction::operator =(+    ThreadSafeFunction&& other) {+  if (*_tsfn != nullptr) {+    Error::Fatal("ThreadSafeFunction::operator =",+        "You cannot assign a new TSFN because existing one is still alive.");+    return *this;+  }+  _tsfn = std::move(other._tsfn);+  other._tsfn.reset();+  return *this;+}++inline napi_status ThreadSafeFunction::BlockingCall() const {+  return CallInternal(nullptr, napi_tsfn_blocking);+}++template <typename Callback>+inline napi_status ThreadSafeFunction::BlockingCall(+    Callback callback) const {+  return CallInternal(new CallbackWrapper(callback), napi_tsfn_blocking);+}++template <typename DataType, typename Callback>+inline napi_status ThreadSafeFunction::BlockingCall(+    DataType* data, Callback callback) const {+  auto wrapper = [data, callback](Env env, Function jsCallback) {+    callback(env, jsCallback, data);+  };+  return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_blocking);+}++inline napi_status ThreadSafeFunction::NonBlockingCall() const {+  return CallInternal(nullptr, napi_tsfn_nonblocking);+}++template <typename Callback>+inline napi_status ThreadSafeFunction::NonBlockingCall(+    Callback callback) const {+  return CallInternal(new CallbackWrapper(callback), napi_tsfn_nonblocking);+}++template <typename DataType, typename Callback>+inline napi_status ThreadSafeFunction::NonBlockingCall(+    DataType* data, Callback callback) const {+  auto wrapper = [data, callback](Env env, Function jsCallback) {+    callback(env, jsCallback, data);+  };+  return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_nonblocking);+}++inline napi_status ThreadSafeFunction::Acquire() const {+  return napi_acquire_threadsafe_function(*_tsfn);+}++inline napi_status ThreadSafeFunction::Release() {+  return napi_release_threadsafe_function(*_tsfn, napi_tsfn_release);+}++inline napi_status ThreadSafeFunction::Abort() {+  return napi_release_threadsafe_function(*_tsfn, napi_tsfn_abort);+}++inline ThreadSafeFunction::ConvertibleContext+ThreadSafeFunction::GetContext() const {+  void* context;+  napi_get_threadsafe_function_context(*_tsfn, &context);+  return ConvertibleContext({ context });+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  const Object& resource,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data,+                                                  napi_finalize wrapper) {+  static_assert(details::can_make_string<ResourceString>::value+      || std::is_convertible<ResourceString, napi_value>::value,+      "Resource name should be string convertible type");

Done

romandev

comment created time in 2 months

Pull request review commentnodejs/node-addon-api

Implement ThreadSafeFunction class

 inline void AsyncWorker::OnWorkComplete(   } } +////////////////////////////////////////////////////////////////////////////////+// ThreadSafeFunction class+////////////////////////////////////////////////////////////////////////////////++// static+template <typename ResourceString>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount);+}++// static+template <typename ResourceString, typename ContextType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context);+}++// static+template <typename ResourceString, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, finalizeCallback);+}++// static+template <typename ResourceString, typename Finalizer,+          typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, finalizeCallback, data);+}++// static+template <typename ResourceString, typename ContextType, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback);+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback, data);+}++// static+template <typename ResourceString>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */);+}++// static+template <typename ResourceString, typename ContextType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context,+             [](Env, ContextType*) {} /* empty finalizer */);+}++// static+template <typename ResourceString, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */,+             finalizeCallback, static_cast<void*>(nullptr) /* data */,+             details::ThreadSafeFinalize<void, Finalizer>::Wrapper);+}++// static+template <typename ResourceString, typename Finalizer,+          typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */,+             finalizeCallback, data,+             details::ThreadSafeFinalize<+                 void, Finalizer, FinalizerDataType>::WrapperWithData);+}++// static+template <typename ResourceString, typename ContextType, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback,+             static_cast<void*>(nullptr) /* data */,+             details::ThreadSafeFinalize<+                 ContextType, Finalizer>::WrapperWithContext);+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  const Object& resource,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback, data,+             details::ThreadSafeFinalize<ContextType, Finalizer,+                 FinalizerDataType>::WrapperWithDataAndContext);+}++inline ThreadSafeFunction::ThreadSafeFunction()+  : _tsfn(std::make_unique<napi_threadsafe_function>(nullptr)) {+}++inline ThreadSafeFunction::ThreadSafeFunction(+    napi_threadsafe_function tsfn)+  : _tsfn(std::make_unique<napi_threadsafe_function>(tsfn)) {+}++inline ThreadSafeFunction::ThreadSafeFunction(ThreadSafeFunction&& other)+  : _tsfn(std::move(other._tsfn)) {+  other._tsfn.reset();+}++inline ThreadSafeFunction& ThreadSafeFunction::operator =(+    ThreadSafeFunction&& other) {+  if (*_tsfn != nullptr) {+    Error::Fatal("ThreadSafeFunction::operator =",+        "You cannot assign a new TSFN because existing one is still alive.");+    return *this;+  }+  _tsfn = std::move(other._tsfn);+  other._tsfn.reset();+  return *this;+}++inline napi_status ThreadSafeFunction::BlockingCall() const {+  return CallInternal(nullptr, napi_tsfn_blocking);+}++template <typename Callback>+inline napi_status ThreadSafeFunction::BlockingCall(+    Callback callback) const {+  return CallInternal(new CallbackWrapper(callback), napi_tsfn_blocking);+}++template <typename DataType, typename Callback>+inline napi_status ThreadSafeFunction::BlockingCall(+    DataType* data, Callback callback) const {+  auto wrapper = [data, callback](Env env, Function jsCallback) {+    callback(env, jsCallback, data);+  };+  return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_blocking);+}++inline napi_status ThreadSafeFunction::NonBlockingCall() const {+  return CallInternal(nullptr, napi_tsfn_nonblocking);+}++template <typename Callback>+inline napi_status ThreadSafeFunction::NonBlockingCall(+    Callback callback) const {+  return CallInternal(new CallbackWrapper(callback), napi_tsfn_nonblocking);+}++template <typename DataType, typename Callback>+inline napi_status ThreadSafeFunction::NonBlockingCall(+    DataType* data, Callback callback) const {+  auto wrapper = [data, callback](Env env, Function jsCallback) {+    callback(env, jsCallback, data);+  };+  return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_nonblocking);+}++inline napi_status ThreadSafeFunction::Acquire() const {+  return napi_acquire_threadsafe_function(*_tsfn);+}++inline napi_status ThreadSafeFunction::Release() {+  return napi_release_threadsafe_function(*_tsfn, napi_tsfn_release);+}++inline napi_status ThreadSafeFunction::Abort() {+  return napi_release_threadsafe_function(*_tsfn, napi_tsfn_abort);+}++inline ThreadSafeFunction::ConvertibleContext+ThreadSafeFunction::GetContext() const {+  void* context;+  napi_get_threadsafe_function_context(*_tsfn, &context);+  return ConvertibleContext({ context });+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  const Object& resource,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data,+                                                  napi_finalize wrapper) {+  static_assert(details::can_make_string<ResourceString>::value+      || std::is_convertible<ResourceString, napi_value>::value,+      "Resource name should be string convertible type");++  ThreadSafeFunction tsfn;+  auto* finalizeData = new details::ThreadSafeFinalize<ContextType, Finalizer,+      FinalizerDataType>({ data, finalizeCallback, tsfn._tsfn.get() });+  napi_status status = napi_create_threadsafe_function(env, callback, resource,+      Value::From(env, resourceName), maxQueueSize, initialThreadCount,+      finalizeData, wrapper, context, CallJS, tsfn._tsfn.get());+  if (status != napi_ok) {+    delete finalizeData;+    NAPI_THROW_IF_FAILED(env, status, ThreadSafeFunction());+  }++  return tsfn;+}++inline napi_status ThreadSafeFunction::CallInternal(+    CallbackWrapper* callbackWrapper,+    napi_threadsafe_function_call_mode mode) const {+  napi_status status = napi_call_threadsafe_function(+      *_tsfn, callbackWrapper, mode);+  if (status != napi_ok && callbackWrapper != nullptr) {+    delete callbackWrapper;+  }++  return status;+}++// static+inline void ThreadSafeFunction::CallJS(napi_env env,+                                       napi_value jsCallback,+                                       void* /* context */,+                                       void* data) {+  if (env == nullptr && jsCallback == nullptr)+    return;++  if (data != nullptr) {+    auto* callbackWrapper = static_cast<CallbackWrapper*>(data);+    (*callbackWrapper)(env, Function(env, jsCallback));+    delete callbackWrapper;+  } else {

Done

romandev

comment created time in 2 months

Pull request review commentnodejs/node-addon-api

Implement ThreadSafeFunction class

 inline void AsyncWorker::OnWorkComplete(   } } +////////////////////////////////////////////////////////////////////////////////+// ThreadSafeFunction class+////////////////////////////////////////////////////////////////////////////////++// static+template <typename ResourceString>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount);+}++// static+template <typename ResourceString, typename ContextType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context);+}++// static+template <typename ResourceString, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, finalizeCallback);+}++// static+template <typename ResourceString, typename Finalizer,+          typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, finalizeCallback, data);+}++// static+template <typename ResourceString, typename ContextType, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback);+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data) {+  return New(env, callback, Object(), resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback, data);+}++// static+template <typename ResourceString>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */);+}++// static+template <typename ResourceString, typename ContextType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context,+             [](Env, ContextType*) {} /* empty finalizer */);+}++// static+template <typename ResourceString, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */,+             finalizeCallback, static_cast<void*>(nullptr) /* data */,+             details::ThreadSafeFinalize<void, Finalizer>::Wrapper);+}++// static+template <typename ResourceString, typename Finalizer,+          typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  Finalizer finalizeCallback,+                                  FinalizerDataType* data) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, static_cast<void*>(nullptr) /* context */,+             finalizeCallback, data,+             details::ThreadSafeFinalize<+                 void, Finalizer, FinalizerDataType>::WrapperWithData);+}++// static+template <typename ResourceString, typename ContextType, typename Finalizer>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                  const Function& callback,+                                  const Object& resource,+                                  ResourceString resourceName,+                                  size_t maxQueueSize,+                                  size_t initialThreadCount,+                                  ContextType* context,+                                  Finalizer finalizeCallback) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback,+             static_cast<void*>(nullptr) /* data */,+             details::ThreadSafeFinalize<+                 ContextType, Finalizer>::WrapperWithContext);+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  const Object& resource,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data) {+  return New(env, callback, resource, resourceName, maxQueueSize,+             initialThreadCount, context, finalizeCallback, data,+             details::ThreadSafeFinalize<ContextType, Finalizer,+                 FinalizerDataType>::WrapperWithDataAndContext);+}++inline ThreadSafeFunction::ThreadSafeFunction()+  : _tsfn(std::make_unique<napi_threadsafe_function>(nullptr)) {+}++inline ThreadSafeFunction::ThreadSafeFunction(+    napi_threadsafe_function tsfn)+  : _tsfn(std::make_unique<napi_threadsafe_function>(tsfn)) {+}++inline ThreadSafeFunction::ThreadSafeFunction(ThreadSafeFunction&& other)+  : _tsfn(std::move(other._tsfn)) {+  other._tsfn.reset();+}++inline ThreadSafeFunction& ThreadSafeFunction::operator =(+    ThreadSafeFunction&& other) {+  if (*_tsfn != nullptr) {+    Error::Fatal("ThreadSafeFunction::operator =",+        "You cannot assign a new TSFN because existing one is still alive.");+    return *this;+  }+  _tsfn = std::move(other._tsfn);+  other._tsfn.reset();+  return *this;+}++inline napi_status ThreadSafeFunction::BlockingCall() const {+  return CallInternal(nullptr, napi_tsfn_blocking);+}++template <typename Callback>+inline napi_status ThreadSafeFunction::BlockingCall(+    Callback callback) const {+  return CallInternal(new CallbackWrapper(callback), napi_tsfn_blocking);+}++template <typename DataType, typename Callback>+inline napi_status ThreadSafeFunction::BlockingCall(+    DataType* data, Callback callback) const {+  auto wrapper = [data, callback](Env env, Function jsCallback) {+    callback(env, jsCallback, data);+  };+  return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_blocking);+}++inline napi_status ThreadSafeFunction::NonBlockingCall() const {+  return CallInternal(nullptr, napi_tsfn_nonblocking);+}++template <typename Callback>+inline napi_status ThreadSafeFunction::NonBlockingCall(+    Callback callback) const {+  return CallInternal(new CallbackWrapper(callback), napi_tsfn_nonblocking);+}++template <typename DataType, typename Callback>+inline napi_status ThreadSafeFunction::NonBlockingCall(+    DataType* data, Callback callback) const {+  auto wrapper = [data, callback](Env env, Function jsCallback) {+    callback(env, jsCallback, data);+  };+  return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_nonblocking);+}++inline napi_status ThreadSafeFunction::Acquire() const {+  return napi_acquire_threadsafe_function(*_tsfn);+}++inline napi_status ThreadSafeFunction::Release() {+  return napi_release_threadsafe_function(*_tsfn, napi_tsfn_release);+}++inline napi_status ThreadSafeFunction::Abort() {+  return napi_release_threadsafe_function(*_tsfn, napi_tsfn_abort);+}++inline ThreadSafeFunction::ConvertibleContext+ThreadSafeFunction::GetContext() const {+  void* context;+  napi_get_threadsafe_function_context(*_tsfn, &context);+  return ConvertibleContext({ context });+}++// static+template <typename ResourceString, typename ContextType,+          typename Finalizer, typename FinalizerDataType>+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,+                                                  const Function& callback,+                                                  const Object& resource,+                                                  ResourceString resourceName,+                                                  size_t maxQueueSize,+                                                  size_t initialThreadCount,+                                                  ContextType* context,+                                                  Finalizer finalizeCallback,+                                                  FinalizerDataType* data,+                                                  napi_finalize wrapper) {+  static_assert(details::can_make_string<ResourceString>::value+      || std::is_convertible<ResourceString, napi_value>::value,+      "Resource name should be string convertible type");++  ThreadSafeFunction tsfn;+  auto* finalizeData = new details::ThreadSafeFinalize<ContextType, Finalizer,+      FinalizerDataType>({ data, finalizeCallback, tsfn._tsfn.get() });+  napi_status status = napi_create_threadsafe_function(env, callback, resource,+      Value::From(env, resourceName), maxQueueSize, initialThreadCount,+      finalizeData, wrapper, context, CallJS, tsfn._tsfn.get());+  if (status != napi_ok) {+    delete finalizeData;+    NAPI_THROW_IF_FAILED(env, status, ThreadSafeFunction());+  }++  return tsfn;+}++inline napi_status ThreadSafeFunction::CallInternal(+    CallbackWrapper* callbackWrapper,+    napi_threadsafe_function_call_mode mode) const {+  napi_status status = napi_call_threadsafe_function(+      *_tsfn, callbackWrapper, mode);+  if (status != napi_ok && callbackWrapper != nullptr) {+    delete callbackWrapper;+  }++  return status;+}++// static+inline void ThreadSafeFunction::CallJS(napi_env env,+                                       napi_value jsCallback,+                                       void* /* context */,+                                       void* data) {+  if (env == nullptr && jsCallback == nullptr)+    return;

Done

romandev

comment created time in 2 months

Pull request review commentnodejs/node-addon-api

Implement ThreadSafeFunction class

 struct FinalizeData {   Hint* hint; }; +template <typename ContextType=void,+          typename Finalizer=std::function<void(Env, void*, ContextType*)>,+          typename FinalizerDataType=void>+struct ThreadSafeFinalize {+  static inline+  void Wrapper(napi_env env, void* rawFinalizeData, void* /* rawContext */) {+    if (rawFinalizeData == nullptr)+      return;++    ThreadSafeFinalize* finalizeData =+        static_cast<ThreadSafeFinalize*>(rawFinalizeData);+    finalizeData->callback(Env(env));+    if (finalizeData->tsfn) {+      *finalizeData->tsfn = nullptr;+    }+    delete finalizeData;+  }++  static inline+  void WrapperWithData(napi_env env,+                       void* rawFinalizeData,+                       void* /* rawContext */) {+    if (rawFinalizeData == nullptr)+      return;++    ThreadSafeFinalize* finalizeData =+        static_cast<ThreadSafeFinalize*>(rawFinalizeData);+    finalizeData->callback(Env(env), finalizeData->data);+    if (finalizeData->tsfn) {+      *finalizeData->tsfn = nullptr;+    }+    delete finalizeData;+  }++  static inline+  void WrapperWithContext(napi_env env,+                          void* rawFinalizeData,+                          void* rawContext) {+    if (rawFinalizeData == nullptr)+      return;++    ThreadSafeFinalize* finalizeData =+        static_cast<ThreadSafeFinalize*>(rawFinalizeData);+    finalizeData->callback(Env(env), static_cast<ContextType*>(rawContext));+    if (finalizeData->tsfn) {+      *finalizeData->tsfn = nullptr;+    }+    delete finalizeData;+  }++  static inline+  void WrapperWithDataAndContext(napi_env env,

Done

romandev

comment created time in 2 months

Pull request review commentnodejs/node-addon-api

Implement ThreadSafeFunction class

 struct FinalizeData {   Hint* hint; }; +template <typename ContextType=void,+          typename Finalizer=std::function<void(Env, void*, ContextType*)>,+          typename FinalizerDataType=void>+struct ThreadSafeFinalize {+  static inline+  void Wrapper(napi_env env, void* rawFinalizeData, void* /* rawContext */) {+    if (rawFinalizeData == nullptr)+      return;++    ThreadSafeFinalize* finalizeData =+        static_cast<ThreadSafeFinalize*>(rawFinalizeData);+    finalizeData->callback(Env(env));+    if (finalizeData->tsfn) {+      *finalizeData->tsfn = nullptr;+    }+    delete finalizeData;+  }++  static inline+  void WrapperWithData(napi_env env,

Done

romandev

comment created time in 2 months

Pull request review commentnodejs/node-addon-api

Implement ThreadSafeFunction class

 struct FinalizeData {   Hint* hint; }; +template <typename ContextType=void,+          typename Finalizer=std::function<void(Env, void*, ContextType*)>,+          typename FinalizerDataType=void>+struct ThreadSafeFinalize {+  static inline+  void Wrapper(napi_env env, void* rawFinalizeData, void* /* rawContext */) {+    if (rawFinalizeData == nullptr)+      return;++    ThreadSafeFinalize* finalizeData =+        static_cast<ThreadSafeFinalize*>(rawFinalizeData);+    finalizeData->callback(Env(env));+    if (finalizeData->tsfn) {+      *finalizeData->tsfn = nullptr;+    }+    delete finalizeData;+  }++  static inline+  void WrapperWithData(napi_env env,+                       void* rawFinalizeData,+                       void* /* rawContext */) {+    if (rawFinalizeData == nullptr)+      return;++    ThreadSafeFinalize* finalizeData =+        static_cast<ThreadSafeFinalize*>(rawFinalizeData);+    finalizeData->callback(Env(env), finalizeData->data);+    if (finalizeData->tsfn) {+      *finalizeData->tsfn = nullptr;+    }+    delete finalizeData;+  }++  static inline+  void WrapperWithContext(napi_env env,

Done

romandev

comment created time in 2 months

pull request commentnodejs/node-addon-api

Implement ThreadSafeFunction class

@KevinEady Thank you for your update.

I'm not doing anything too "crazy" and not really using all your PRs features to the fullest

I think that we can fix the problem in follow-up PR before release if we found some problem :)

I'm not sure how we want to proceed... I don't know if I target this nodejs repo instead but I created a PR against your fork for now. We can figure out the right approach later,

I recommend that you forks node/node-addon-api and then send a new PR apart from my PR. It's not problem because your .md file change is not depending on my PR. (It will make your change easier to review.)

but take a look at ...

Looks overall good to me. BTW, you might have to match the format with existing documents as follows (e.g. AsyncContext):

ThreadSafeFunction
  ...
Methods
  ...
Operator
  ...
Example
  ...
romandev

comment created time in 3 months

pull request commentw3c/test-results

Update Samsung Internet 9.4 implementation report

@ianbjacobs PTAL

romandev

comment created time in 3 months

PR opened w3c/test-results

Update Samsung Internet 9.4 implementation report
+1438 -2713

0 comment

6 changed files

pr created time in 3 months

push eventromandev/w3c-test-results

Jinho Bang

commit sha 5b8a143fcbda7f42c99c68665ebcbadce046062a

Update Samsung Internet 9.4 implementation report

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha 26de22a1a49682c6f4e10194ff07bf7ec3f87ae7

Create CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha 19d294e4c180df1a18d356dbbf893d12bffba9a6

Delete CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha 4a0db9f38aa7501add848ddf901c65a0cdacf096

Create CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha 23aacd4dc4d42f4aaecfeb65b00acb20cb3b00fd

Delete CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha b2f6ecb585267b6e9ae84edb373df893f4a2ed96

Create CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha bdd21b87d289da1abbf3dcfcc7e99d24b86d8ca0

Delete CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha 3adb6e9b4abe6c55e9b3979111a0a3530f0ac6ef

Create CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha c37d112dd47f4324f5dc82fcc412a96d3ad03292

Delete CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha 168c4ffb68beafd104c7cc54a7b7e0a4cb2b89ab

Create CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha 33b9c40f767565f62f0fe9e5d831d1ed7430bef7

Delete CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha f67e92966c895d840226f530467d7125e3a51b95

Create CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha bb99c62c377a6a32906f08b31078c3468f4c4c87

Delete CNAME

view details

push time in 3 months

push eventromandev/romandev.github.io

Jinho Bang

commit sha 89ec1630fc39ad0cb2536d127942fe65d3db28d6

Create CNAME

view details

push time in 3 months

create barnchromandev/romandev.github.io

branch : master

created branch time in 3 months

push eventromandev/proxy

Jinho Bang

commit sha b1c58a25b2b3a8ebb1f730299d157970c7f0fa62

Update proxy.pac

view details

push time in 3 months

push eventromandev/proxy

Jinho Bang

commit sha 581693a5d2b446f8564a745ee1983e70bcee6288

Update proxy.pac

view details

push time in 3 months

more