X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=src%2Fsel_thread.c;h=f086fa6f1e0372c8562abc4dd593a9477682ed10;hb=a2df84f2250bbe1dc2ac610687e784c73b10e8e9;hp=7bd62dc268926b57ee03621d7eb819a1c84f51fd;hpb=df1262e4bb33b78f429baec77e2c68e4d6c9d592;p=pazpar2-moved-to-github.git diff --git a/src/sel_thread.c b/src/sel_thread.c index 7bd62dc..f086fa6 100644 --- a/src/sel_thread.c +++ b/src/sel_thread.c @@ -1,4 +1,4 @@ -/* $Id: sel_thread.c,v 1.1 2007-04-20 10:06:52 adam Exp $ +/* $Id: sel_thread.c,v 1.3 2007-04-20 11:44:58 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -29,12 +29,27 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#include struct work_item { void *data; struct work_item *next; }; +static struct work_item *queue_remove_last(struct work_item **q) +{ + struct work_item **work_p = q, *work_this = 0; + + while (*work_p && (*work_p)->next) + work_p = &(*work_p)->next; + if (*work_p) + { + work_this = *work_p; + *work_p = 0; + } + return work_this; +} + struct sel_thread { int fd[2]; NMEM nmem; @@ -54,7 +69,7 @@ static void *sel_thread_handler(void *vp) while(1) { - struct work_item **work_p, *work_this; + struct work_item *work_this = 0; /* wait for some work */ pthread_mutex_lock(&p->mutex); while (!p->stop_flag && !p->input_queue) @@ -63,16 +78,16 @@ static void *sel_thread_handler(void *vp) if (p->stop_flag) break; /* got something. Take the last one out of input_queue */ - work_p = &p->input_queue; - while ((*work_p)->next) - work_p = &(*work_p)->next; - work_this = *work_p; - *work_p = 0; + + assert(p->input_queue); + work_this = queue_remove_last(&p->input_queue); + assert(work_this); + pthread_mutex_unlock(&p->mutex); /* work on this item */ p->work_handler(work_this->data); - + /* put it back into output queue */ pthread_mutex_lock(&p->mutex); work_this->next = p->output_queue; @@ -87,7 +102,7 @@ static void *sel_thread_handler(void *vp) } sel_thread_t sel_thread_create(void (*work_handler)(void *work_data), - int *read_fd) + int *read_fd) { NMEM nmem = nmem_create(); sel_thread_t p = nmem_malloc(nmem, sizeof(*p)); @@ -114,7 +129,6 @@ sel_thread_t sel_thread_create(void (*work_handler)(void *work_data), void sel_thread_destroy(sel_thread_t p) { pthread_mutex_lock(&p->mutex); - p->stop_flag = 1; pthread_cond_broadcast(&p->input_data); pthread_mutex_unlock(&p->mutex); @@ -133,37 +147,43 @@ void sel_thread_add(sel_thread_t p, void *data) struct work_item *work_p; pthread_mutex_lock(&p->mutex); - work_p = p->free_queue; - if (!work_p) + + if (p->free_queue) + { + work_p = p->free_queue; + p->free_queue = p->free_queue->next; + } + else work_p = nmem_malloc(p->nmem, sizeof(*work_p)); work_p->data = data; work_p->next = p->input_queue; p->input_queue = work_p; + + pthread_cond_signal(&p->input_data); pthread_mutex_unlock(&p->mutex); } void *sel_thread_result(sel_thread_t p) { - struct work_item **work_p, *work_this; - void *data; - - /* got something. Take the last one out of output_queue */ - work_p = &p->output_queue; - if (!*work_p) - return 0; - while ((*work_p)->next) - work_p = &(*work_p)->next; - work_this = *work_p; - *work_p = 0; + struct work_item *work_this = 0; + void *data = 0; + char read_buf[1]; - /* put freed item in free list */ - work_this->next = p->free_queue; - p->free_queue = work_this; + pthread_mutex_lock(&p->mutex); - data = work_this->data; + /* got something. Take the last one out of output_queue */ + work_this = queue_remove_last(&p->output_queue); + if (work_this) + { + /* put freed item in free list */ + work_this->next = p->free_queue; + p->free_queue = work_this; + + data = work_this->data; + read(p->fd[0], read_buf, 1); + } pthread_mutex_unlock(&p->mutex); - return data; }