From 683544964229388933d5f9a7722a2327312ad5d3 Mon Sep 17 00:00:00 2001 From: Alexander Epaneshnikov Date: Thu, 11 Jun 2026 11:34:40 +0300 Subject: [PATCH] fixup! softsynth: bound the wait for espeak to acknowledge a stop request --- src/espeakup.c | 15 ++++++++++++++- src/softsynth.c | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/espeakup.c b/src/espeakup.c index baeee11..1e39aaf 100644 --- a/src/espeakup.c +++ b/src/espeakup.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "espeakup.h" @@ -41,7 +42,8 @@ espeak_AUDIO_OUTPUT audio_mode; pthread_cond_t runner_awake = PTHREAD_COND_INITIALIZER; pthread_cond_t wake_stop = PTHREAD_COND_INITIALIZER; -pthread_cond_t stop_acknowledged = PTHREAD_COND_INITIALIZER; +/* Initialized in main: uses the monotonic clock for timed waits. */ +pthread_cond_t stop_acknowledged; pthread_mutex_t queue_guard = PTHREAD_MUTEX_INITIALIZER; int espeakup_start_daemon(void) @@ -147,6 +149,17 @@ int main(int argc, char **argv) struct synth_t s = { .voice = "", }; + pthread_condattr_t monotonic_attr; + + /* Condition variables used with pthread_cond_timedwait must use the + * monotonic clock, so that wall-clock adjustments (NTP, an + * installer setting the system time) cannot make the timeouts fire + * too early or far too late. */ + pthread_condattr_init(&monotonic_attr); + pthread_condattr_setclock(&monotonic_attr, CLOCK_MONOTONIC); + pthread_cond_init(&stop_acknowledged, &monotonic_attr); + pthread_condattr_destroy(&monotonic_attr); + synth_queue = new_queue(); if (!synth_queue) { diff --git a/src/softsynth.c b/src/softsynth.c index d2fe585..e382b32 100644 --- a/src/softsynth.c +++ b/src/softsynth.c @@ -237,7 +237,7 @@ static void request_espeak_stop(void) stop_requested = 1; pthread_cond_signal(&runner_awake); // Wake runner, if necessary. pthread_cond_signal(&wake_stop); // Wake runner, if necessary. - clock_gettime(CLOCK_REALTIME, &timeout); + clock_gettime(CLOCK_MONOTONIC, &timeout); timeout.tv_sec += stopAckTimeout; while (should_run && stop_requested && err != ETIMEDOUT) // wait for acknowledgement.