diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-01-03 09:44:54 +0000 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-01-03 09:44:54 +0000 |
commit | 29d9729292d44d2827054a1aef27278f3dadd57e (patch) | |
tree | dcede7f015fd4c4d1ef7ccd311a505bfdc79e1c2 | |
parent | a05de60a5670c759b5dbe6e60bbac8fe9332420d (diff) | |
download | rsyslog-29d9729292d44d2827054a1aef27278f3dadd57e.tar.gz rsyslog-29d9729292d44d2827054a1aef27278f3dadd57e.tar.xz rsyslog-29d9729292d44d2827054a1aef27278f3dadd57e.zip |
moved queue code to its own module (finally)
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | queue.c | 128 | ||||
-rw-r--r-- | queue.h | 71 | ||||
-rw-r--r-- | syslogd.c | 1 | ||||
-rw-r--r-- | threads.c | 88 | ||||
-rw-r--r-- | threads.h | 20 |
6 files changed, 202 insertions, 108 deletions
diff --git a/Makefile.am b/Makefile.am index 4f3ee472..f4e60f30 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,8 @@ rsyslogd_SOURCES = \ liblogging-stub.h \ threads.c \ threads.h \ + queue.c \ + queue.h \ sync.c \ sync.h \ net.c \ diff --git a/queue.c b/queue.c new file mode 100644 index 00000000..95eb8907 --- /dev/null +++ b/queue.c @@ -0,0 +1,128 @@ +/* queue.c + * + * This file implements the queue object and its several queueing methods. + * + * File begun on 2008-01-03 by RGerhards + * + * Copyright 2008 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog 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. + * + * Rsyslog 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 Rsyslog. If not, see <http://www.gnu.org/licenses/>. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" + +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <pthread.h> + +#include "rsyslog.h" +#include "queue.h" + +/* static data */ +int iMainMsgQueueSize; +msgQueue *pMsgQueue = NULL; + +/* methods */ + +/* queue functions (may be migrated to some other file...) + */ + + +msgQueue *queueInit (void) +{ + msgQueue *q; + + q = (msgQueue *)malloc(sizeof(msgQueue)); + if (q == NULL) return (NULL); + if((q->pbuf = malloc(sizeof(void *) * iMainMsgQueueSize)) == NULL) { + free(q); + return NULL; + } + + q->empty = 1; + q->full = 0; + q->head = 0; + q->tail = 0; + q->mut = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); + pthread_mutex_init (q->mut, NULL); + q->notFull = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + pthread_cond_init (q->notFull, NULL); + q->notEmpty = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + pthread_cond_init (q->notEmpty, NULL); + + return (q); +} + +void queueDelete (msgQueue *q) +{ + pthread_mutex_destroy (q->mut); + free (q->mut); + pthread_cond_destroy (q->notFull); + free (q->notFull); + pthread_cond_destroy (q->notEmpty); + free (q->notEmpty); + free(q->pbuf); + free (q); +} + + +/* In queueAdd() and queueDel() we have a potential race condition. If a message + * is dequeued and at the same time a message is enqueued and the queue is either + * full or empty, the full (or empty) indicator may be invalidly updated. HOWEVER, + * this does not cause any real problems. No queue pointers can be wrong. And even + * if one of the flags is set invalidly, that does not pose a real problem. If + * "full" is invalidly set, at mose one message might be lost, if we are already in + * a timeout situation (this is quite acceptable). And if "empty" is accidently set, + * the receiver will not continue the inner loop, but break out of the outer. So no + * harm is done at all. For this reason, I do not yet use a mutex to guard the two + * flags - there would be a notable performance hit with, IMHO, no gain in stability + * or functionality. But anyhow, now it's documented... + * rgerhards, 2007-09-20 + * NOTE: this comment does not really apply - the callers handle the mutex, so it + * *is* guarded. + */ +void queueAdd (msgQueue *q, void* in) +{ + q->pbuf[q->tail] = in; + q->tail++; + if (q->tail == iMainMsgQueueSize) + q->tail = 0; + if (q->tail == q->head) + q->full = 1; + q->empty = 0; + + return; +} + +void queueDel(msgQueue *q, void **out) +{ + *out = (void*) q->pbuf[q->head]; + + q->head++; + if (q->head == iMainMsgQueueSize) + q->head = 0; + if (q->head == q->tail) + q->empty = 1; + q->full = 0; + + return; +} + +/* + * vi:set ai: + */ diff --git a/queue.h b/queue.h new file mode 100644 index 00000000..dd74faba --- /dev/null +++ b/queue.h @@ -0,0 +1,71 @@ +/* Definition of the queue support module. + * + * Copyright 2008 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog 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. + * + * Rsyslog 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 Rsyslog. If not, see <http://www.gnu.org/licenses/>. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ + +#ifndef QUEUE_H_INCLUDED +#define QUEUE_H_INCLUDED + + +/* queue types */ +typedef enum { + QUEUETYPE_FIXED_ARRAY, /* a simple queue made out of a fixed (initially malloced) array fast but memoryhog */ + QUEUETYPE_LINKEDLIST, /* linked list used as buffer, lower fixed memory overhead but slower */ +} queueTypes_t; + +/* the queue object */ +typedef struct { + queueTypes_t qType; + int iMaxQueSize; /* how large can the queue grow? */ + void** pUsr; /* the queued user data structure */ + /* synchronization variables */ + pthread_mutex_t *mut; + pthread_cond_t *notFull, *notEmpty; + int full, empty; + /* end sync variables */ + union { /* different data elements based on queue type (qType) */ + struct { + long head, tail; + } farray; + } tVars; +} queue_t; + +/* this is the first approach to a queue, this time with static + * memory. + */ +typedef struct { + void** pbuf; + long head, tail; + int full, empty; + pthread_mutex_t *mut; + pthread_cond_t *notFull, *notEmpty; +} msgQueue; + +/* prototypes */ +msgQueue *queueInit (void); +void queueDelete (msgQueue *q); +void queueAdd (msgQueue *q, void* in); +void queueDel (msgQueue *q, void **out); + +/* go-away's */ +extern int iMainMsgQueueSize; +extern msgQueue *pMsgQueue; + +#endif /* #ifndef QUEUE_H_INCLUDED */ @@ -208,6 +208,7 @@ #include "omfile.h" #include "omdiscard.h" #include "threads.h" +#include "queue.h" /* We define our own set of syslog defintions so that we * do not need to rely on (possibly different) implementations. @@ -41,10 +41,6 @@ #include "linkedlist.h" #include "threads.h" -/* static data */ -int iMainMsgQueueSize; -msgQueue *pMsgQueue = NULL; - /* linked list of currently-known threads */ static linkedList_t llThrds; @@ -263,90 +259,6 @@ thrdSleep(thrdInfo_t *pThis, int iSeconds, int iuSeconds) } -/* queue functions (may be migrated to some other file...) - */ - - -msgQueue *queueInit (void) -{ - msgQueue *q; - - q = (msgQueue *)malloc(sizeof(msgQueue)); - if (q == NULL) return (NULL); - if((q->pbuf = malloc(sizeof(void *) * iMainMsgQueueSize)) == NULL) { - free(q); - return NULL; - } - - q->empty = 1; - q->full = 0; - q->head = 0; - q->tail = 0; - q->mut = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); - pthread_mutex_init (q->mut, NULL); - q->notFull = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); - pthread_cond_init (q->notFull, NULL); - q->notEmpty = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); - pthread_cond_init (q->notEmpty, NULL); - - return (q); -} - -void queueDelete (msgQueue *q) -{ - pthread_mutex_destroy (q->mut); - free (q->mut); - pthread_cond_destroy (q->notFull); - free (q->notFull); - pthread_cond_destroy (q->notEmpty); - free (q->notEmpty); - free(q->pbuf); - free (q); -} - - -/* In queueAdd() and queueDel() we have a potential race condition. If a message - * is dequeued and at the same time a message is enqueued and the queue is either - * full or empty, the full (or empty) indicator may be invalidly updated. HOWEVER, - * this does not cause any real problems. No queue pointers can be wrong. And even - * if one of the flags is set invalidly, that does not pose a real problem. If - * "full" is invalidly set, at mose one message might be lost, if we are already in - * a timeout situation (this is quite acceptable). And if "empty" is accidently set, - * the receiver will not continue the inner loop, but break out of the outer. So no - * harm is done at all. For this reason, I do not yet use a mutex to guard the two - * flags - there would be a notable performance hit with, IMHO, no gain in stability - * or functionality. But anyhow, now it's documented... - * rgerhards, 2007-09-20 - * NOTE: this comment does not really apply - the callers handle the mutex, so it - * *is* guarded. - */ -void queueAdd (msgQueue *q, void* in) -{ - q->pbuf[q->tail] = in; - q->tail++; - if (q->tail == iMainMsgQueueSize) - q->tail = 0; - if (q->tail == q->head) - q->full = 1; - q->empty = 0; - - return; -} - -void queueDel(msgQueue *q, void **out) -{ - *out = (void*) q->pbuf[q->head]; - - q->head++; - if (q->head == iMainMsgQueueSize) - q->head = 0; - if (q->head == q->tail) - q->empty = 1; - q->full = 0; - - return; -} - /* * vi:set ai: */ @@ -41,17 +41,6 @@ typedef struct thrdInfo { pthread_t thrdID; } thrdInfo_t; -/* this is the first approach to a queue, this time with static - * memory. - */ -typedef struct { - void** pbuf; - long head, tail; - int full, empty; - pthread_mutex_t *mut; - pthread_cond_t *notFull, *notEmpty; -} msgQueue; - /* prototypes */ rsRetVal thrdExit(void); rsRetVal thrdInit(void); @@ -59,15 +48,6 @@ rsRetVal thrdTerminate(thrdInfo_t *pThis); rsRetVal thrdTerminateAll(void); rsRetVal thrdCreate(rsRetVal (*thrdMain)(thrdInfo_t*), eTermSyncType_t eTermSyncType, rsRetVal(*afterRun)(thrdInfo_t *)); rsRetVal thrdSleep(thrdInfo_t *pThis, int iSeconds, int iuSeconds); -msgQueue *queueInit (void); -void queueDelete (msgQueue *q); -void queueAdd (msgQueue *q, void* in); -void queueDel (msgQueue *q, void **out); - -/* go-away's */ -extern int iMainMsgQueueSize; -extern msgQueue *pMsgQueue; - /* macros (replace inline functions) */ /*TODO: remove these macros once we now we can live without -- rgerhards, 2007-12-20 |