@@ -213,8 +213,7 @@ class ThreadSafeFunction {
213213 resource,
214214 *v8::String::Utf8Value (env_->isolate, name)),
215215 thread_count(thread_count_),
216- is_closing(false ),
217- is_closed(false ),
216+ state(OPEN),
218217 dispatch_state(kDispatchIdle ),
219218 context(context_),
220219 max_queue_size(max_queue_size_),
@@ -237,14 +236,14 @@ class ThreadSafeFunction {
237236 node::Mutex::ScopedLock lock (this ->mutex );
238237
239238 while (queue.size () >= max_queue_size && max_queue_size > 0 &&
240- !is_closing ) {
239+ state == OPEN ) {
241240 if (mode == napi_tsfn_nonblocking) {
242241 return napi_queue_full;
243242 }
244243 cond->Wait (lock);
245244 }
246245
247- if (!is_closing ) {
246+ if (state == OPEN ) {
248247 queue.push (data);
249248 Send ();
250249 return napi_ok;
@@ -253,7 +252,7 @@ class ThreadSafeFunction {
253252 return napi_invalid_arg;
254253 }
255254 thread_count--;
256- if (!is_closed || thread_count > 0 ) {
255+ if (!(state == CLOSED && thread_count == 0 ) ) {
257256 return napi_closing;
258257 }
259258 }
@@ -265,13 +264,13 @@ class ThreadSafeFunction {
265264 napi_status Acquire () {
266265 node::Mutex::ScopedLock lock (this ->mutex );
267266
268- if (is_closing) {
269- return napi_closing;
270- }
267+ if (state == OPEN) {
268+ thread_count++;
271269
272- thread_count++;
270+ return napi_ok;
271+ }
273272
274- return napi_ok ;
273+ return napi_closing ;
275274 }
276275
277276 napi_status Release (napi_threadsafe_function_release_mode mode) {
@@ -285,16 +284,18 @@ class ThreadSafeFunction {
285284 thread_count--;
286285
287286 if (thread_count == 0 || mode == napi_tsfn_abort) {
288- if (!is_closing) {
289- is_closing = (mode == napi_tsfn_abort);
290- if (is_closing && max_queue_size > 0 ) {
287+ if (state == OPEN) {
288+ if (mode == napi_tsfn_abort) {
289+ state = CLOSING;
290+ }
291+ if (state == CLOSING && max_queue_size > 0 ) {
291292 cond->Signal (lock);
292293 }
293294 Send ();
294295 }
295296 }
296297
297- if (!is_closed || thread_count > 0 ) {
298+ if (!(state == CLOSED && thread_count == 0 ) ) {
298299 return napi_ok;
299300 }
300301 }
@@ -372,8 +373,8 @@ class ThreadSafeFunction {
372373
373374 protected:
374375 void ReleaseResources () {
375- if (!is_closed ) {
376- is_closed = true ;
376+ if (state != CLOSED ) {
377+ state = CLOSED ;
377378 ref.Reset ();
378379 node::RemoveEnvironmentCleanupHook (env->isolate , Cleanup, this );
379380 env->Unref ();
@@ -409,9 +410,7 @@ class ThreadSafeFunction {
409410
410411 {
411412 node::Mutex::ScopedLock lock (this ->mutex );
412- if (is_closing) {
413- CloseHandlesAndMaybeDelete ();
414- } else {
413+ if (state == OPEN) {
415414 size_t size = queue.size ();
416415 if (size > 0 ) {
417416 data = queue.front ();
@@ -425,7 +424,7 @@ class ThreadSafeFunction {
425424
426425 if (size == 0 ) {
427426 if (thread_count == 0 ) {
428- is_closing = true ;
427+ state = CLOSING ;
429428 if (max_queue_size > 0 ) {
430429 cond->Signal (lock);
431430 }
@@ -434,6 +433,8 @@ class ThreadSafeFunction {
434433 } else {
435434 has_more = true ;
436435 }
436+ } else {
437+ CloseHandlesAndMaybeDelete ();
437438 }
438439 }
439440
@@ -466,7 +467,7 @@ class ThreadSafeFunction {
466467 v8::HandleScope scope (env->isolate );
467468 if (set_closing) {
468469 node::Mutex::ScopedLock lock (this ->mutex );
469- is_closing = true ;
470+ state = CLOSING ;
470471 if (max_queue_size > 0 ) {
471472 cond->Signal (lock);
472473 }
@@ -538,6 +539,8 @@ class ThreadSafeFunction {
538539 using node::AsyncResource::CallbackScope;
539540 };
540541
542+ enum State : unsigned char { OPEN, CLOSING, CLOSED };
543+
541544 static const unsigned char kDispatchIdle = 0 ;
542545 static const unsigned char kDispatchRunning = 1 << 0 ;
543546 static const unsigned char kDispatchPending = 1 << 1 ;
@@ -552,8 +555,7 @@ class ThreadSafeFunction {
552555 std::queue<void *> queue;
553556 uv_async_t async;
554557 size_t thread_count;
555- bool is_closing;
556- bool is_closed;
558+ State state;
557559 std::atomic_uchar dispatch_state;
558560
559561 // These are variables set once, upon creation, and then never again, which
0 commit comments