diff --git a/spa/include/spa/support/loop.h b/spa/include/spa/support/loop.h index 7dc55f3ae..6c68e0785 100644 --- a/spa/include/spa/support/loop.h +++ b/spa/include/spa/support/loop.h @@ -109,8 +109,11 @@ struct spa_loop_methods { * an object that has identity. * \param size The size of data to copy. * \param block If \true, do not return until func has been called. Otherwise, - * returns immediately. Passing \true does not risk a deadlock because - * the data thread is never allowed to wait on any other thread. + * returns immediately. Passing \true can cause a deadlock when + * the calling thread is holding the loop context lock. A blocking + * invoke should never be done from a realtime thread. Also beware + * of blocking invokes between 2 threads as you can easily end up + * in a deadly embrace. * \param user_data An opaque pointer passed to func. * \return `-EPIPE` if the internal ring buffer filled up, * if block is \false, 0 if seq was SPA_ID_INVALID or diff --git a/spa/plugins/support/loop.c b/spa/plugins/support/loop.c index 2d2ca8656..5688bebe7 100644 --- a/spa/plugins/support/loop.c +++ b/spa/plugins/support/loop.c @@ -365,14 +365,10 @@ retry: if (block && queue->ack_fd != -1) { uint64_t count = 1; - spa_loop_control_hook_before(&impl->hooks_list); - if ((res = spa_system_eventfd_read(impl->system, queue->ack_fd, &count)) < 0) spa_log_warn(impl->log, "%p: failed to read event fd:%d: %s", queue, queue->ack_fd, spa_strerror(res)); - spa_loop_control_hook_after(&impl->hooks_list); - res = item->res; } else {