From dc7831707f795a911f4ca7a727f55eafe6e84b78 Mon Sep 17 00:00:00 2001 From: Andreas Streichardt Date: Fri, 21 Feb 2025 14:35:11 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix=20hanging=20shutdown?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit also fixed multiple occasions where errorCallback must be set --- includes/NSFW.h | 1 + js/src/index.js | 2 ++ src/NSFW.cpp | 38 +++++++++++++++++++++++++++----------- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/includes/NSFW.h b/includes/NSFW.h index e65fc17..7c38a44 100644 --- a/includes/NSFW.h +++ b/includes/NSFW.h @@ -122,6 +122,7 @@ class NSFW : public Napi::ObjectWrap { }; Napi::Value UpdateExcludedPaths(const Napi::CallbackInfo &info); + Napi::Value Close(const Napi::CallbackInfo &info); public: static Napi::Object Init(Napi::Env, Napi::Object exports); diff --git a/js/src/index.js b/js/src/index.js index 86ae655..2dee1b2 100644 --- a/js/src/index.js +++ b/js/src/index.js @@ -48,6 +48,7 @@ function NSFWFilePoller(watchPath, eventCallback, debounceMS) { this.pause = () => this.stop(); this.resume = () => this.start(); + this.close = () => this.close(); } @@ -112,6 +113,7 @@ function nsfw(watchPath, eventCallback, options) { this.resume = () => implementation.resume(); this.getExcludedPaths = () => implementation.getExcludedPaths(); this.updateExcludedPaths = (paths) => implementation.updateExcludedPaths(paths); + this.close = () => implementation.close(); } diff --git a/src/NSFW.cpp b/src/NSFW.cpp index d616a04..0e96342 100644 --- a/src/NSFW.cpp +++ b/src/NSFW.cpp @@ -145,7 +145,9 @@ void NSFW::StartWorker::Execute() { std::lock_guard lock(mNSFW->mRunningLock); mNSFW->mRunning = true; } - mNSFW->mErrorCallback.Acquire(); + if (mNSFW->mErrorCallback) { + mNSFW->mErrorCallback.Acquire(); + } mNSFW->mEventCallback.Acquire(); mNSFW->mPollThread = std::thread([] (NSFW *nsfw) { nsfw->pollForEvents(); }, mNSFW); } else { @@ -388,14 +390,16 @@ void NSFW::pollForEvents() { std::lock_guard lock(mInterfaceLock); if (mInterface->hasErrored()) { - const std::string &error = mInterface->getError(); - mErrorCallback.NonBlockingCall([error](Napi::Env env, Napi::Function jsCallback) { - Napi::Value jsError = Napi::Error::New(env, error).Value(); - jsCallback.Call({ jsError }); - }); - { - std::lock_guard lock(mRunningLock); - mRunning = false; + if (mErrorCallback) { + const std::string &error = mInterface->getError(); + mErrorCallback.NonBlockingCall([error](Napi::Env env, Napi::Function jsCallback) { + Napi::Value jsError = Napi::Error::New(env, error).Value(); + jsCallback.Call({ jsError }); + }); + { + std::lock_guard lock(mRunningLock); + mRunning = false; + } } break; } @@ -447,7 +451,9 @@ void NSFW::pollForEvents() { // If we are destroying NFSW object (destructor) we cannot release the thread safe functions at this point // or we get a segfault if (!mFinalizing) { - mErrorCallback.Release(); + if (mErrorCallback) { + mErrorCallback.Release(); + } mEventCallback.Release(); } } @@ -463,6 +469,14 @@ Napi::Value NSFW::ExcludedPaths() { return path_array; } +Napi::Value NSFW::Close(const Napi::CallbackInfo &info) { + mEventCallback.Release(); + if (mErrorCallback) { + mErrorCallback.Release(); + } + return Napi::Value(); +} + Napi::Value NSFW::InstanceCount(const Napi::CallbackInfo &info) { return Napi::Number::New(info.Env(), instanceCount); } @@ -476,9 +490,11 @@ Napi::Object NSFW::Init(Napi::Env env, Napi::Object exports) { InstanceMethod("pause", &NSFW::Pause), InstanceMethod("resume", &NSFW::Resume), InstanceMethod("getExcludedPaths", &NSFW::GetExcludedPaths), - InstanceMethod("updateExcludedPaths", &NSFW::UpdateExcludedPaths) + InstanceMethod("updateExcludedPaths", &NSFW::UpdateExcludedPaths), + InstanceMethod("close", &NSFW::Close) }); + if (gcEnabled) { nsfwConstructor.DefineProperty(Napi::PropertyDescriptor::Function( "getAllocatedInstanceCount",