Skip to content

Commit 3547016

Browse files
committed
n-api: fix dead lock if multi push events
- add waiting_task_size to record waiting push events - compare max_queue_size before queue.size which would be faster Signed-off-by: milkpotatoes <chenshulin5@huawei.com>
1 parent d6dade5 commit 3547016

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

src/node_api.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ class ThreadSafeFunction : public node::AsyncResource {
218218
dispatch_state(kDispatchIdle),
219219
context(context_),
220220
max_queue_size(max_queue_size_),
221+
waiting_task_size(0),
221222
env(env_),
222223
finalize_data(finalize_data_),
223224
finalize_cb(finalize_cb_),
@@ -238,12 +239,14 @@ class ThreadSafeFunction : public node::AsyncResource {
238239
napi_status Push(void* data, napi_threadsafe_function_call_mode mode) {
239240
node::Mutex::ScopedLock lock(this->mutex);
240241

241-
while (queue.size() >= max_queue_size && max_queue_size > 0 &&
242+
while (max_queue_size > 0 && queue.size() >= max_queue_size &&
242243
!is_closing) {
243244
if (mode == napi_tsfn_nonblocking) {
244245
return napi_queue_full;
245246
}
247+
waiting_task_size++;
246248
cond->Wait(lock);
249+
waiting_task_size--;
247250
}
248251

249252
if (is_closing) {
@@ -385,7 +388,7 @@ class ThreadSafeFunction : public node::AsyncResource {
385388
data = queue.front();
386389
queue.pop();
387390
popped_value = true;
388-
if (size == max_queue_size && max_queue_size > 0) {
391+
if (waiting_task_size > 0) {
389392
cond->Signal(lock);
390393
}
391394
size--;
@@ -518,6 +521,7 @@ class ThreadSafeFunction : public node::AsyncResource {
518521
// means we don't need the mutex to read them.
519522
void* context;
520523
size_t max_queue_size;
524+
size_t waiting_task_size;
521525

522526
// These are variables accessed only from the loop thread.
523527
v8impl::Persistent<v8::Function> ref;

0 commit comments

Comments
 (0)