File tree Expand file tree Collapse file tree 1 file changed +27
-4
lines changed Expand file tree Collapse file tree 1 file changed +27
-4
lines changed Original file line number Diff line number Diff line change @@ -127,10 +127,33 @@ napi_status ThreadSafeFunction::call(
127
127
if (isBlocking == napi_tsfn_nonblocking) {
128
128
return napi_queue_full;
129
129
}
130
- queueCv_.wait (lock, [&] {
131
- return queue_.size () < maxQueueSize_ || isClosingOrAborted ();
132
- });
133
- if (isClosingOrAborted ()) return napi_closing;
130
+
131
+ // In blocking mode with full queue: process queue immediately to avoid
132
+ // deadlock when called from JS thread. Release lock during processing.
133
+ lock.unlock ();
134
+ const auto invoker = callInvoker_.lock ();
135
+ if (invoker) {
136
+ invoker->invokeSync (
137
+ [self = shared_from_this ()] { self->processQueue (); });
138
+ }
139
+ lock.lock ();
140
+
141
+ // After processing, wait if queue is still full
142
+ if (maxQueueSize_ && queue_.size () >= maxQueueSize_) {
143
+ queueCv_.wait (lock, [&] {
144
+ return queue_.size () < maxQueueSize_ || isClosingOrAborted ();
145
+ });
146
+ // Re-check conditions after waiting
147
+ if (isClosingOrAborted ()) return napi_closing;
148
+ // Double-check queue size in case of spurious wakeup or race condition
149
+ if (maxQueueSize_ && queue_.size () >= maxQueueSize_) {
150
+ return napi_queue_full;
151
+ }
152
+ }
153
+ }
154
+ // Final check before pushing - ensure we're not closing and have space
155
+ if (isClosingOrAborted ()) {
156
+ return napi_closing;
134
157
}
135
158
queue_.push (data);
136
159
}
You can’t perform that action at this time.
0 commit comments