mirror of
https://github.com/linux-speakup/espeakup.git
synced 2026-08-09 09:19:09 +02:00
espeak: back off before retrying after any espeak error
When processing an entry failed, only EE_BUFFER_FULL throttled before the retry; any other persistent error (e.g. EE_INTERNAL_ERROR after espeak was terminated) made queue_process_entry retry the same entry in a tight loop with no sleep, burning a whole CPU while printing to a stderr that points to /dev/null in daemon mode. Factor the one-second throttle out into espeak_wait_retry() and apply it to every failed entry. The wake_stop condition variable still interrupts the wait immediately when a flush comes in. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e92edf96dc
commit
7405455baf
1 changed files with 20 additions and 10 deletions
30
src/espeak.c
30
src/espeak.c
|
|
@ -24,6 +24,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "espeakup.h"
|
#include "espeakup.h"
|
||||||
|
|
||||||
|
|
@ -344,6 +345,19 @@ static void reinitialize_espeak(struct synth_t *s)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wait for up to a second before retrying an entry which could not be
|
||||||
|
* processed, so that we do not busy-loop on a persistent error. Called
|
||||||
|
* and returns with queue_guard held. Wakes up immediately if a stop is
|
||||||
|
* requested. */
|
||||||
|
static void espeak_wait_retry(void)
|
||||||
|
{
|
||||||
|
struct timespec timeout;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_REALTIME, &timeout);
|
||||||
|
timeout.tv_sec++;
|
||||||
|
pthread_cond_timedwait(&wake_stop, &queue_guard, &timeout);
|
||||||
|
}
|
||||||
|
|
||||||
static struct espeak_entry_t *current = NULL;
|
static struct espeak_entry_t *current = NULL;
|
||||||
static void queue_process_entry(struct synth_t *s)
|
static void queue_process_entry(struct synth_t *s)
|
||||||
{
|
{
|
||||||
|
|
@ -419,17 +433,13 @@ static void queue_process_entry(struct synth_t *s)
|
||||||
free_espeak_entry(current);
|
free_espeak_entry(current);
|
||||||
current = NULL;
|
current = NULL;
|
||||||
} else {
|
} else {
|
||||||
if (error == EE_BUFFER_FULL)
|
if (error != EE_BUFFER_FULL)
|
||||||
{
|
|
||||||
/* Give speak a little break before retrying */
|
|
||||||
struct timespec timeout;
|
|
||||||
clock_gettime(CLOCK_REALTIME, &timeout);
|
|
||||||
timeout.tv_sec++;
|
|
||||||
/* But wake up immediately if we have to stop */
|
|
||||||
pthread_cond_timedwait(&wake_stop, &queue_guard, &timeout);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fprintf(stderr, "espeak error: %d\n", error);
|
fprintf(stderr, "espeak error: %d\n", error);
|
||||||
|
/* The entry stays queued and will be retried. Give espeak a
|
||||||
|
* little break before that, whatever the error: previously only
|
||||||
|
* EE_BUFFER_FULL throttled, and any other persistent error made
|
||||||
|
* us retry the same entry in a tight loop, burning a whole CPU. */
|
||||||
|
espeak_wait_retry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue