Completely data-agnostic queue functions.

The functions in queue.c no longer use static variables.  We can now use
them for multiple queues, if necessary.
This commit is contained in:
Christopher Brannon 2009-06-29 17:54:09 -05:00 committed by William Hubbs
commit 31ad5f04ca
5 changed files with 56 additions and 34 deletions

View file

@ -33,6 +33,7 @@ const char *Version = "0.71";
const char *pidPath = "/var/run/espeakup.pid";
int debug = 0;
struct queue_t *synth_queue = NULL;
int self_pipe_fds[2];
volatile int should_run = 1;
@ -82,6 +83,12 @@ int main(int argc, char **argv)
struct synth_t s = {
.voice = "",
};
synth_queue = new_queue();
if (!synth_queue) {
fprintf(stderr, "Unable to allocate memory.\n");
return 2;
}
/* process command line options */
process_cli(argc, argv);

View file

@ -63,12 +63,16 @@ struct synth_t {
int len;
};
struct queue_t; /* An opaque type. */
extern struct queue_t *synth_queue;
extern int debug;
extern void process_cli(int argc, char **argv);
extern void queue_add(void *entry);
extern void queue_remove(void);
extern void *queue_peek(void);
extern struct queue_t *new_queue(void);
extern void queue_add(struct queue_t *q, void *entry);
extern void queue_remove(struct queue_t *q);
extern void *queue_peek(struct queue_t *q);
extern void *signal_thread(void *arg);
extern int initialize_espeak(struct synth_t *s);
extern void *espeak_thread(void *arg);

51
queue.c
View file

@ -31,48 +31,59 @@ struct queue_entry_t {
struct queue_entry_t *next;
};
static struct queue_entry_t *head = NULL;
static struct queue_entry_t *tail = NULL;
struct queue_t {
struct queue_entry_t *head, *tail;
};
void queue_add(void *data)
struct queue_t *new_queue(void)
{
struct queue_entry_t *tmp;
struct queue_t *q = malloc(sizeof(struct queue_t));
if (q != NULL) {
q->head = NULL;
q->tail = NULL;
}
return q;
}
void queue_add(struct queue_t *q, void *data)
{
struct queue_entry_t *tmp;
assert(data);
tmp = malloc(sizeof(struct queue_entry_t));
if (! tmp) {
if (!tmp) {
printf("Unable to allocate memory for queue entry.\n");
return;
}
tmp->data = data;
tmp->next = NULL;
if (! tail) {
tail = tmp;
if (!q->tail) {
q->tail = tmp;
} else {
tail->next = tmp;
tail = tail->next;
q->tail->next = tmp;
q->tail = q->tail->next;
}
if (!head)
head = tmp;
if (!q->head)
q->head = tmp;
}
void queue_remove(void)
void queue_remove(struct queue_t *q)
{
struct queue_entry_t *tmp;
if (head) {
tmp = head;
head = tmp->next;
if (q->head) {
tmp = q->head;
q->head = tmp->next;
free(tmp);
if (!head)
tail = head;
if (!q->head)
q->tail = q->head;
}
}
void *queue_peek(void)
void *queue_peek(struct queue_t *q)
{
if (head)
return head->data;
if (q->head)
return q->head->data;
else
return NULL;
}

View file

@ -48,7 +48,7 @@ static void queue_add_cmd(enum command_t cmd, enum adjust_t adj, int value)
entry->adjust = adj;
entry->value = value;
pthread_mutex_lock(&queue_guard);
queue_add((void *) entry);
queue_add(synth_queue, (void *) entry);
pthread_cond_signal(&runner_awake);
pthread_mutex_unlock(&queue_guard);
}
@ -72,7 +72,7 @@ static void queue_add_text(char *txt, size_t length)
}
entry->len = length;
pthread_mutex_lock(&queue_guard);
queue_add((void *) entry);
queue_add(synth_queue, (void *) entry);
pthread_cond_signal(&runner_awake);
pthread_mutex_unlock(&queue_guard);
}

18
synth.c
View file

@ -150,15 +150,15 @@ static void free_espeak_entry(struct espeak_entry_t *entry)
free(entry);
}
static void queue_clear()
static void synth_queue_clear()
{
struct espeak_entry_t *current;
current = (struct espeak_entry_t *) queue_peek();
current = (struct espeak_entry_t *) queue_peek(synth_queue);
while (current) {
free_espeak_entry(current);
queue_remove();
current = (struct espeak_entry_t *) queue_peek();
queue_remove(synth_queue);
current = (struct espeak_entry_t *) queue_peek(synth_queue);
}
}
@ -167,7 +167,7 @@ static void queue_process_entry(struct synth_t *s)
espeak_ERROR error;
struct espeak_entry_t *current;
current = (struct espeak_entry_t *) queue_peek();
current = (struct espeak_entry_t *) queue_peek(synth_queue);
pthread_mutex_unlock(&queue_guard);
if (current) {
switch (current->cmd) {
@ -201,7 +201,7 @@ static void queue_process_entry(struct synth_t *s)
if (error == EE_OK) {
free_espeak_entry(current);
pthread_mutex_lock(&queue_guard);
queue_remove();
queue_remove(synth_queue);
pthread_mutex_unlock(&queue_guard);
}
}
@ -263,17 +263,17 @@ void *espeak_thread(void *arg)
pthread_mutex_lock(&queue_guard);
while (should_run) {
while (should_run && !queue_peek() && !runner_must_stop)
while (should_run && !queue_peek(synth_queue) && !runner_must_stop)
pthread_cond_wait(&runner_awake, &queue_guard);
if (runner_must_stop) {
queue_clear();
synth_queue_clear();
stop_speech();
runner_must_stop = 0;
pthread_cond_signal(&stop_acknowledged);
}
while (should_run && queue_peek() && !runner_must_stop) {
while (should_run && queue_peek(synth_queue) && !runner_must_stop) {
queue_process_entry(s);
pthread_mutex_lock(&queue_guard);
}