Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schulhof <gabriel.schulhof@intel.com>2020-04-06 20:16:15 +0300
committerGabriel Schulhof <gabriel.schulhof@intel.com>2020-04-09 12:41:28 +0300
commitaeb7084fe6446350ec032e9819746126811bf44f (patch)
treeb1173c9ecd5c049f5af7298c181e587b437cd60d /src/node_api.cc
parentb82d72c199e70a0c9fbeb6c06715ef8120b3de2f (diff)
n-api: detect deadlocks in thread-safe function
We introduce status `napi_would_deadlock` to be used as a return status by `napi_call_threadsafe_function` if the call is made with `napi_tsfn_blocking` on the main thread and the queue is full. PR-URL: https://github.com/nodejs/node/pull/32689 Fixes: https://github.com/nodejs/node/issues/32615 Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'src/node_api.cc')
-rw-r--r--src/node_api.cc5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/node_api.cc b/src/node_api.cc
index fad9cf72a97..552538c6f05 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -129,6 +129,7 @@ class ThreadSafeFunction : public node::AsyncResource {
is_closing(false),
context(context_),
max_queue_size(max_queue_size_),
+ main_thread(uv_thread_self()),
env(env_),
finalize_data(finalize_data_),
finalize_cb(finalize_cb_),
@@ -148,12 +149,15 @@ class ThreadSafeFunction : public node::AsyncResource {
napi_status Push(void* data, napi_threadsafe_function_call_mode mode) {
node::Mutex::ScopedLock lock(this->mutex);
+ uv_thread_t current_thread = uv_thread_self();
while (queue.size() >= max_queue_size &&
max_queue_size > 0 &&
!is_closing) {
if (mode == napi_tsfn_nonblocking) {
return napi_queue_full;
+ } else if (uv_thread_equal(&current_thread, &main_thread)) {
+ return napi_would_deadlock;
}
cond->Wait(lock);
}
@@ -434,6 +438,7 @@ class ThreadSafeFunction : public node::AsyncResource {
// means we don't need the mutex to read them.
void* context;
size_t max_queue_size;
+ uv_thread_t main_thread;
// These are variables accessed only from the loop thread.
v8impl::Persistent<v8::Function> ref;