aboutsummaryrefslogtreecommitdiffstats
path: root/daemon/fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/fifo.c')
-rw-r--r--daemon/fifo.c75
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;
}