diff --git a/Makefile b/Makefile
index 059db6b..f784aac 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,7 @@ SRCS = \
cli.c \
espeakup.c \
queue.c \
+ signal.c \
softsynth.c \
synth.c
diff --git a/espeakup.c b/espeakup.c
index 34c1257..db86232 100644
--- a/espeakup.c
+++ b/espeakup.c
@@ -43,6 +43,7 @@ char *defaultVoice = NULL;
int debug = 0;
volatile int stopped = 0;
+volatile int should_run = 1;
espeak_AUDIO_OUTPUT audio_mode;
int espeakup_is_running(void)
@@ -75,27 +76,14 @@ int create_pid_file(void)
return 0;
}
-void espeakup_sighandler(int sig)
-{
- if (debug)
- printf("Caught signal %i\n", sig);
-
- /* clear the queue */
- stop_runner();
-
- /* shut down espeak and close the softsynth */
- espeak_Terminate();
- close_softsynth();
-
- if (!debug)
- unlink(pidPath);
- exit(0);
-}
-
int main(int argc, char **argv)
{
+ sigset_t sigset;
int rate;
+ int err;
+ pthread_t signal_thread_id;
pthread_t queue_thread_id;
+ pthread_t softsynth_thread_id;
struct synth_t s = {
.voice = "",
};
@@ -115,54 +103,37 @@ int main(int argc, char **argv)
return 3;
}
- /* register signal handler */
- signal(SIGINT, espeakup_sighandler);
- signal(SIGTERM, espeakup_sighandler);
-
-
+/*
+ * If we are not in debug mode, become a daemon and store the pid.
+ */
if (!debug) {
- /* become a daemon */
daemon(0, 1);
-
- /* write our pid file. */
if (create_pid_file() < 0) {
perror("Unable to create pid file");
return 2;
}
}
- /* initialize espeak */
- select_audio_mode();
- rate = espeak_Initialize(audio_mode, 0, NULL, 0);
- if (rate < 0) {
- fprintf(stderr, "Unable to initialize espeak.\n");
- return 5;
- }
-
- if (init_audio((unsigned int) rate) < 0) {
- return 6;
- }
-
- /* Setup initial voice parameters */
- if (defaultVoice) {
- set_voice(&s, defaultVoice);
- free(defaultVoice);
- defaultVoice = NULL;
- }
- set_frequency(&s, defaultFrequency, ADJ_SET);
- set_pitch(&s, defaultPitch, ADJ_SET);
- set_rate(&s, defaultRate, ADJ_SET);
- set_volume(&s, defaultVolume, ADJ_SET);
- espeak_SetParameter(espeakCAPITALS, 0, 0);
-
- /* Spawn our queue-processing thread. */
- int err = pthread_create(&queue_thread_id, NULL, &queue_runner, &s);
+ /* create the signal processing thread here. */
+ err = pthread_create(&signal_thread_id, NULL, &signal_thread, NULL);
if (err != 0) {
return 4;
}
- /* run the main loop */
- main_loop(&s);
+ /*
+ * Set up the signal mask which will be the default for all threads.
+ * We are handling sigint and sigterm, so block them.
+ */
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGTERM);
+ sigprocmask(SIG_BLOCK, &sigset, NULL);
+
+ /* Spawn our queue-processing thread. */
+ err = pthread_create(&queue_thread_id, NULL, &queue_runner, &s);
+ if (err != 0) {
+ return 4;
+ }
return 0;
}
diff --git a/espeakup.h b/espeakup.h
index 5433a77..dc1f567 100644
--- a/espeakup.h
+++ b/espeakup.h
@@ -76,9 +76,10 @@ extern espeak_ERROR stop_speech(void);
extern espeak_ERROR speak_text(struct synth_t *s);
extern int open_softsynth(void);
extern void close_softsynth(void);
+extern void *reader_thread(void *arg);
extern void stop_runner(void);
-extern void main_loop(struct synth_t *s);
extern void *queue_runner(void *arg);
+extern void *signal_thread(void *arg);
extern void select_audio_mode(void);
extern int init_audio(unsigned int rate);
extern void lock_audio_mutex(void);
diff --git a/signal.c b/signal.c
new file mode 100644
index 0000000..10e0b90
--- /dev/null
+++ b/signal.c
@@ -0,0 +1,62 @@
+/*
+ * espeakup - interface which allows speakup to use espeak
+ *
+ * Copyright (C) 2008 William Hubbs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#include "espeakup.h"
+
+/*
+ * We install a dummy signal handler to let the o/s know that we
+ * do not want the default action to be performed since we are
+ * handling the signal.
+ */
+static void dummy_handler(int sig)
+{
+}
+
+void *signal_thread(void *arg)
+{
+ struct sigaction temp;
+ sigset_t sigset;
+ int sig;
+ int should_run = 1;
+
+ /* install dummy handlers for the signals we want to process */
+ temp.sa_handler = dummy_handler;
+ sigemptyset(&temp.sa_mask);
+ sigaction(SIGINT, &temp, NULL);
+ sigaction(SIGTERM, &temp, NULL);
+
+ while(should_run) {
+ sigfillset(&sigset);
+ sigwait(&sigset, &sig);
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ printf("This is where we shut down.\n");
+ should_run = 0;
+ break;
+ default:
+ printf("espeakup caught signal %d\n", sig);
+ break;
+ }
+ }
+ return NULL;
+}
diff --git a/softsynth.c b/softsynth.c
index 1a93edb..d04f6e4 100644
--- a/softsynth.c
+++ b/softsynth.c
@@ -35,6 +35,23 @@ const int synthFlushChar = 0x18;
static int softFD = 0;
+int open_softsynth(void)
+{
+ int rc;
+
+ softFD = open("/dev/softsynth", O_RDWR | O_NONBLOCK);
+ if (softFD < 0)
+ rc = 0;
+ else
+ rc = 1;
+ return rc;
+}
+
+void close_softsynth(void)
+{
+ close(softFD);
+}
+
static int process_command(struct synth_t *s, char *buf, int start)
{
char *cp;
@@ -125,34 +142,18 @@ static void process_buffer(struct synth_t *s, char *buf, ssize_t length)
}
}
-int open_softsynth(void)
-{
- int rc;
-
- softFD = open("/dev/softsynth", O_RDWR | O_NONBLOCK);
- if (softFD < 0)
- rc = 0;
- else
- rc = 1;
- return rc;
-}
-
-void close_softsynth(void)
-{
- close(softFD);
-}
-
-void main_loop(struct synth_t *s)
+void *reader_thread(void *arg)
{
+ struct synth_t *s = (struct synth_t *) arg;
fd_set set;
ssize_t length;
char buf[maxBufferSize];
char *cp;
- while (1) {
-
+ while (should_run) {
FD_ZERO(&set);
FD_SET(softFD, &set);
+
if (select(softFD + 1, &set, NULL, NULL, NULL) < 0) {
if (errno == EINTR)
continue;
@@ -179,4 +180,5 @@ void main_loop(struct synth_t *s)
}
process_buffer(s, buf, length);
}
+ return NULL;
}