From bf4ebda92bd34127d496d9edc0d33c6c6beb1ca5 Mon Sep 17 00:00:00 2001 From: John French Date: Tue, 4 Jun 2019 12:21:51 -0700 Subject: [PATCH] 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 --- doc/async_worker.md | 13 +++++++++++++ napi-inl.h | 6 +++++- napi.h | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/async_worker.md b/doc/async_worker.md index 43e11d5..da12cba 100644 --- a/doc/async_worker.md +++ b/doc/async_worker.md @@ -125,6 +125,19 @@ class was created, passing in the error as the first parameter. virtual void Napi::AsyncWorker::OnError(const Napi::Error& e); ``` +### Destroy + +This method is invoked when the instance must be deallocated. If +`SuppressDestruct()` was not called then this method will be called after either +`OnError()` or `OnOK()` complete. The default implementation of this method +causes the instance to delete itself using the `delete` operator. The method is +provided so as to ensure that instances allocated by means other than the `new` +operator can be deallocated upon work completion. + +```cpp +virtual void Napi::AsyncWorker::Destroy(); +``` + ### Constructor Creates a new `Napi::AsyncWorker`. diff --git a/napi-inl.h b/napi-inl.h index 2b91b12..9f03f3a 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -3529,6 +3529,10 @@ inline AsyncWorker::~AsyncWorker() { } } +inline void AsyncWorker::Destroy() { + delete this; +} + inline AsyncWorker::AsyncWorker(AsyncWorker&& other) { _env = other._env; other._env = nullptr; @@ -3623,7 +3627,7 @@ inline void AsyncWorker::OnWorkComplete( }); } if (!self->_suppress_destruct) { - delete self; + self->Destroy(); } } diff --git a/napi.h b/napi.h index 7a83d79..bf565fb 100644 --- a/napi.h +++ b/napi.h @@ -1803,6 +1803,7 @@ namespace Napi { virtual void Execute() = 0; virtual void OnOK(); virtual void OnError(const Error& e); + virtual void Destroy(); void SetError(const std::string& error);