summaryrefslogtreecommitdiffstats
path: root/threads.c
diff options
context:
space:
mode:
Diffstat (limited to 'threads.c')
-rw-r--r--threads.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/threads.c b/threads.c
new file mode 100644
index 00000000..c3aee4b8
--- /dev/null
+++ b/threads.c
@@ -0,0 +1,123 @@
+/* threads.c
+ *
+ * This file implements threading support helpers (and maybe the thread object)
+ * for rsyslog.
+ *
+ * File begun on 2007-12-14 by RGerhards
+ *
+ * Copyright 2007 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 "rsyslog.h"
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "syslogd.h"
+#include "threads.h"
+
+int iMainMsgQueueSize;
+msgQueue *pMsgQueue = NULL;
+
+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:
+ */