diff --git a/espeakup.c b/espeakup.c index d7f49f8..0cf3d0b 100644 --- a/espeakup.c +++ b/espeakup.c @@ -42,7 +42,7 @@ espeak_AUDIO_OUTPUT audio_mode; pthread_cond_t runner_awake = PTHREAD_COND_INITIALIZER; pthread_cond_t stop_acknowledged = PTHREAD_COND_INITIALIZER; pthread_mutex_t queue_guard = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t stop_guard = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t acknowledge_guard = PTHREAD_MUTEX_INITIALIZER; int espeakup_is_running(void) { diff --git a/espeakup.h b/espeakup.h index c529ad4..d5d3f18 100644 --- a/espeakup.h +++ b/espeakup.h @@ -88,6 +88,6 @@ extern espeak_AUDIO_OUTPUT audio_mode; extern pthread_cond_t runner_awake; extern pthread_cond_t stop_acknowledged; extern pthread_mutex_t queue_guard; -extern pthread_mutex_t stop_guard; +extern pthread_mutex_t acknowledge_guard; #endif diff --git a/softsynth.c b/softsynth.c index a78cc23..37e70b3 100644 --- a/softsynth.c +++ b/softsynth.c @@ -167,11 +167,20 @@ static void process_buffer(struct synth_t *s, char *buf, ssize_t length) static void request_espeak_stop(void) { - pthread_mutex_lock(&stop_guard); + pthread_mutex_lock(&acknowledge_guard); + pthread_mutex_lock(&queue_guard); runner_must_stop = 1; + pthread_mutex_unlock(&queue_guard); pthread_cond_signal(&runner_awake); /* Wake runner, if necessary. */ - pthread_cond_wait(&stop_acknowledged, &stop_guard); - pthread_mutex_unlock(&stop_guard); + + /* + * Runner will see runner_must_stop == 1 next time it locks + * queue_guard, or when it awakens. + * It will lock acknowledge_guard, acknowledge the stop, and signal + * the reader, which will awaken. + */ + pthread_cond_wait(&stop_acknowledged, &acknowledge_guard); + pthread_mutex_unlock(&acknowledge_guard); } void *softsynth_thread(void *arg) diff --git a/synth.c b/synth.c index 39d95ea..1bfb0ce 100644 --- a/synth.c +++ b/synth.c @@ -148,7 +148,6 @@ static void queue_process_entry(struct synth_t *s) espeak_ERROR error; struct espeak_entry_t *current; - pthread_mutex_lock(&queue_guard); current = (struct espeak_entry_t *) queue_peek(); pthread_mutex_unlock(&queue_guard); if (current) { @@ -198,14 +197,12 @@ static void queue_clear() { struct espeak_entry_t *current; - pthread_mutex_lock(&queue_guard); current = (struct espeak_entry_t *) queue_peek(); while (current) { free_entry(current); queue_remove(); current = (struct espeak_entry_t *) queue_peek(); } - pthread_mutex_unlock(&queue_guard); } /* espeak_thread is the "main" function of our secondary (queue-processing) @@ -267,11 +264,11 @@ void *espeak_thread(void *arg) } if (runner_must_stop) { - pthread_mutex_lock(&stop_guard); + pthread_mutex_lock(&acknowledge_guard); queue_clear(); stop_speech(); runner_must_stop = 0; - pthread_mutex_unlock(&stop_guard); + pthread_mutex_unlock(&acknowledge_guard); pthread_cond_signal(&stop_acknowledged); } }