@@ -10,7 +10,8 @@ NSFW::NSFW(const Napi::CallbackInfo &info):
1010 mInterface(nullptr ),
1111 mQueue(std::make_shared<EventQueue>()),
1212 mPath(" " ),
13- mRunning(false )
13+ mRunning(false ),
14+ mFinalizing(false )
1415{
1516 auto env = info.Env ();
1617 if (info.Length () < 1 || !info[0 ].IsString ()) {
@@ -74,14 +75,24 @@ NSFW::NSFW(const Napi::CallbackInfo &info):
7475}
7576
7677NSFW::~NSFW () {
77- mErrorCallback .Release ();
78- mEventCallback .Release ();
79-
8078 if (gcEnabled) {
8179 instanceCount--;
8280 }
8381}
8482
83+ void NSFW::Finalize (Napi::Env env) {
84+ if (mRunning ) {
85+ mFinalizing = true ;
86+ {
87+ std::lock_guard<std::mutex> lock (mRunningLock );
88+ mRunning = false ;
89+ }
90+ Unref ();
91+ mWaitPoolEvents .notify_one ();
92+ mPollThread .join ();
93+ }
94+ }
95+
8596NSFW::StartWorker::StartWorker (Napi::Env env, NSFW *nsfw):
8697 Napi::AsyncWorker(env, " nsfw" ),
8798 mDeferred(Napi::Promise::Deferred::New(env)),
@@ -109,7 +120,10 @@ void NSFW::StartWorker::Execute() {
109120
110121 if (mNSFW ->mInterface ->isWatching ()) {
111122 mStatus = STARTED;
112- mNSFW ->mRunning = true ;
123+ {
124+ std::lock_guard<std::mutex> lock (mNSFW ->mRunningLock );
125+ mNSFW ->mRunning = true ;
126+ }
113127 mNSFW ->mErrorCallback .Acquire ();
114128 mNSFW ->mEventCallback .Acquire ();
115129 mNSFW ->mPollThread = std::thread ([] (NSFW *nsfw) { nsfw->pollForEvents (); }, mNSFW );
@@ -171,7 +185,11 @@ void NSFW::StopWorker::Execute() {
171185 }
172186
173187 mDidStopWatching = true ;
174- mNSFW ->mRunning = false ;
188+ {
189+ std::lock_guard<std::mutex> lock (mNSFW ->mRunningLock );
190+ mNSFW ->mRunning = false ;
191+ }
192+ mNSFW ->mWaitPoolEvents .notify_one ();
175193 mNSFW ->mPollThread .join ();
176194
177195 std::lock_guard<std::mutex> lock (mNSFW ->mInterfaceLock );
@@ -271,7 +289,10 @@ void NSFW::pollForEvents() {
271289 Napi::Value jsError = Napi::Error::New (env, error).Value ();
272290 jsCallback.Call ({ jsError });
273291 });
274- mRunning = false ;
292+ {
293+ std::lock_guard<std::mutex> lock (mRunningLock );
294+ mRunning = false ;
295+ }
275296 break ;
276297 }
277298
@@ -310,11 +331,21 @@ void NSFW::pollForEvents() {
310331 }
311332 }
312333
313- std::this_thread::sleep_for (std::chrono::milliseconds (sleepDuration));
334+ std::unique_lock<std::mutex> lck (mRunningLock );
335+ const auto waitUntil = std::chrono::steady_clock::now () + std::chrono::milliseconds (sleepDuration);
336+ mWaitPoolEvents .wait_until (lck, waitUntil,
337+ [this , waitUntil](){
338+ return !mRunning || std::chrono::steady_clock::now () >= waitUntil;
339+ }
340+ );
314341 }
315342
316- mErrorCallback .Release ();
317- mEventCallback .Release ();
343+ // If we are destroying NFSW object (destructor) we cannot release the thread safe functions at this point
344+ // or we get a segfault
345+ if (!mFinalizing ) {
346+ mErrorCallback .Release ();
347+ mEventCallback .Release ();
348+ }
318349}
319350
320351Napi::Value NSFW::InstanceCount (const Napi::CallbackInfo &info) {
0 commit comments