From 2b959e874e26729b7d508a7d4d88eb33f331c24c Mon Sep 17 00:00:00 2001 From: Alexander Epaneshnikov Date: Thu, 11 Jun 2026 11:05:56 +0300 Subject: [PATCH] signal: wake all condition-variable waiters on shutdown On SIGINT/SIGTERM, the signal thread only set should_run to 0 and relied on a wake-up chain to propagate the shutdown: the self-pipe wakes the softsynth thread out of select(), which on exit signals runner_awake to wake the espeak thread. That chain breaks whenever the softsynth thread is not sitting in select() but waiting on stop_acknowledged in request_espeak_stop(): nobody ever signals that condition variable on shutdown, so the thread never re-evaluates should_run and the process never exits. Broadcast all three condition variables after clearing should_run, so that every parked thread re-checks its predicate, whichever wait it is blocked in. Helps: https://github.com/linux-speakup/espeakup/issues/45 Helps: https://github.com/linux-speakup/espeakup/issues/62 Co-Authored-By: Claude --- src/signal.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/signal.c b/src/signal.c index f0b4d57..b6ddefc 100644 --- a/src/signal.c +++ b/src/signal.c @@ -58,6 +58,14 @@ void *signal_thread(void *arg) case SIGTERM: pthread_mutex_lock(&queue_guard); should_run = 0; + /* Wake up any thread waiting on a condition variable so + * that it notices the shutdown request: the softsynth + * thread may be waiting for a stop acknowledgement, and + * the espeak thread may be waiting for work or throttling + * before a retry. */ + pthread_cond_broadcast(&runner_awake); + pthread_cond_broadcast(&wake_stop); + pthread_cond_broadcast(&stop_acknowledged); pthread_mutex_unlock(&queue_guard); break; default: