diff options
Diffstat (limited to 'daemon/fifo.c')
-rw-r--r-- | daemon/fifo.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/daemon/fifo.c b/daemon/fifo.c index 2754885..9daecdf 100644 --- a/daemon/fifo.c +++ b/daemon/fifo.c @@ -1,11 +1,9 @@ /* - * fifo.c - syslogd implementation for windows, simple and fast queue + * fifo.c - syslogd implementation for windows, just a queue + * for the replacement of glib's queue. * * Created by Alexander Yaworsky * - * This replacement eliminates strange page faults which were - * with glib's 2.6.3 queues. - * * THIS SOFTWARE IS NOT COPYRIGHTED * * This source code is offered for use in the public domain. You may @@ -24,6 +22,19 @@ #include <syslog.h> #include <syslogd.h> +struct fifo_item +{ + struct fifo_item *next; /* queue is a single-linked list */ + void *payload; +}; + +struct fifo +{ + struct fifo_item *first; /* first pushed item */ + struct fifo_item *last; /* last pushed item */ + int item_count; +}; + /****************************************************************************** * fifo_create * @@ -32,11 +43,9 @@ struct fifo* fifo_create() { struct fifo *ret = g_malloc( sizeof(struct fifo) ); - struct fifo_item *guard_item= g_malloc( sizeof(struct fifo_item) ); - ret->first = guard_item; - ret->last = guard_item; - guard_item->next = NULL; - guard_item->payload = NULL; + ret->first = NULL; + ret->last = NULL; + ret->item_count = 0; return ret; } @@ -61,45 +70,41 @@ void fifo_destroy( struct fifo* queue ) * fifo_push * * Add item to queue. + * Return TRUE if added item is the first in the queue. */ -void fifo_push( struct fifo* queue, void* data ) +gboolean fifo_push( struct fifo* queue, void* data ) { struct fifo_item *item = g_malloc( sizeof(struct fifo_item) ); item->next = NULL; item->payload = data; - queue->last->next = item; + if( !queue->last ) + queue->first = item; + else + queue->last->next = item; queue->last = item; + return 1 == ++queue->item_count; } /****************************************************************************** * fifo_pop * * Extract item from queue. - * Consider four possible conditions: - * 1) next == NULL, payload == NULL: there is the only one empty item - * in the queue; leave it and return NULL - * 2) next == NULL, payload != NULL: leave item and return its payload; - * set item's payload NULL - * 3) next != NULL, payload == NULL: queue was empty when a new item was - * added; free this item and go to the next one - * 4) next != NULL, payload != NULL: free item and return its payload */ void* fifo_pop( struct fifo* queue ) { - for(;;) - { - struct fifo_item *item = queue->first; - struct fifo_item *next = InterlockedExchangePointer( &item->next, NULL ); - void *data = item->payload; - item->payload = NULL; - if( next ) - { - queue->first = next; - g_free( item ); - } - if( data ) - return data; - if( !next ) - return NULL; - } + struct fifo_item *item; + void *data; + + item = queue->first; + if( !item ) + return NULL; + + queue->first = item->next; + if( !queue->first ) + queue->last = NULL; + + data = item->payload; + g_free( item ); + queue->item_count--; + return data; } |