16using async_fn = std::function<void(msgpack::sbuffer&)>;
36 : Napi::AsyncWorker(env)
52 }
catch (
const std::exception& e) {
57 SetError(
"Unknown exception occurred during async operation");
63 auto buf = Napi::Buffer<char>::Copy(Env(),
_result.data(),
_result.size());
99 auto dummy = Napi::Function::New(env, [](
const Napi::CallbackInfo&) {});
100 _completion_tsfn = Napi::ThreadSafeFunction::New(env, dummy,
"ThreadedAsyncOpComplete", 0, 1);
110 static void Run(Napi::Env env, std::shared_ptr<Napi::Promise::Deferred> deferred,
async_fn fn)
126 auto self = shared_from_this();
129 self->_fn(self->_result);
130 self->_success =
true;
131 }
catch (
const std::exception& e) {
132 self->_error = e.what();
133 self->_success =
false;
135 self->_error =
"Unknown exception occurred during threaded async operation";
136 self->_success =
false;
143 self->_completion_tsfn.BlockingCall([self](Napi::Env env, Napi::Function ) {
144 if (self->_success) {
145 auto buf = Napi::Buffer<char>::Copy(env, self->_result.data(), self->_result.size());
146 self->_deferred->Resolve(buf);
148 auto error = Napi::Error::New(env, self->_error);
149 self->_deferred->Reject(error.Value());
151 self->_completion_tsfn.Release();
163 if (pthread_attr_init(&attr) == 0) {
165 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
169 int rc = pthread_create(
172 [](
void* arg) ->
void* {
173 std::unique_ptr<std::function<void()>> fn(
static_cast<std::function<
void()
>*>(arg));
178 pthread_attr_destroy(&attr);
185 std::unique_ptr<std::function<void()>> reclaimed(heap_work);
Encapsulatest some work that can be done off the JavaScript main thread.
AsyncOperation & operator=(AsyncOperation &&)=delete
AsyncOperation(AsyncOperation &&)=delete
AsyncOperation & operator=(const AsyncOperation &)=delete
AsyncOperation(const AsyncOperation &)=delete
~AsyncOperation() override=default
AsyncOperation(Napi::Env env, std::shared_ptr< Napi::Promise::Deferred > deferred, async_fn fn)
void OnError(const Napi::Error &e) override
std::shared_ptr< Napi::Promise::Deferred > _deferred
Runs work on a dedicated std::thread instead of the libuv thread pool.
ThreadedAsyncOperation & operator=(const ThreadedAsyncOperation &)=delete
ThreadedAsyncOperation(Napi::Env env, std::shared_ptr< Napi::Promise::Deferred > deferred, async_fn fn)
ThreadedAsyncOperation(const ThreadedAsyncOperation &)=delete
~ThreadedAsyncOperation()=default
static void launch_detached_with_large_stack(std::function< void()> work)
std::shared_ptr< Napi::Promise::Deferred > _deferred
static void Run(Napi::Env env, std::shared_ptr< Napi::Promise::Deferred > deferred, async_fn fn)
ThreadedAsyncOperation & operator=(ThreadedAsyncOperation &&)=delete
static constexpr size_t WORKER_STACK_SIZE
Napi::ThreadSafeFunction _completion_tsfn
ThreadedAsyncOperation(ThreadedAsyncOperation &&)=delete
std::function< void(msgpack::sbuffer &)> async_fn
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept