summaryrefslogtreecommitdiff
path: root/tacplus-daemon/queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'tacplus-daemon/queue.c')
-rw-r--r--tacplus-daemon/queue.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/tacplus-daemon/queue.c b/tacplus-daemon/queue.c
new file mode 100644
index 0000000..fae583f
--- /dev/null
+++ b/tacplus-daemon/queue.c
@@ -0,0 +1,127 @@
+/*
+ TACACS+ D-Bus Daemon code
+
+ Copyright (c) 2018 AT&T Intellectual Property.
+ Copyright (c) 2015-2016 Brocade Communications Systems, Inc.
+
+ SPDX-License-Identifier: GPL-2.0-only
+*/
+
+#include "queue.h"
+
+Queue * create_queue(void (*free_element)(void *))
+{
+ Queue *q;
+ q = malloc(sizeof(*q));
+
+ if (q == NULL) {
+ syslog(LOG_ERR, "Failed to allocate queue");
+ }
+ else {
+ q->front = NULL;
+ q->rear = NULL;
+ q->free_element = free_element;
+ pthread_mutex_init(&(q->lock), NULL);
+ pthread_cond_init(&(q->empty), NULL);
+ }
+ return q;
+}
+
+void enqueue(Queue *q, void *e)
+{
+ Node *n;
+
+ if (q == NULL || e == NULL)
+ return;
+
+ pthread_mutex_lock(&(q->lock));
+
+ n = malloc(sizeof(*n));
+ n->element = e;
+ n->next = NULL;
+
+ if (is_queue_empty(q)) {
+ q->front = n;
+ q->rear = n;
+ }
+ else {
+ q->rear->next = n;
+ q->rear = n;
+ }
+ pthread_cond_broadcast(&(q->empty));
+ pthread_mutex_unlock(&(q->lock));
+}
+
+void re_enqueue(Queue *q, void *e)
+{
+ Node *n;
+
+ if (q == NULL || e == NULL)
+ return;
+
+ pthread_mutex_lock(&(q->lock));
+
+ n = malloc(sizeof(*n));
+ n->element = e;
+ n->next = q->front;
+
+ if (is_queue_empty(q)) {
+ q->front = n;
+ q->rear = n;
+ }
+ else {
+ q->front = n;
+ }
+ pthread_cond_broadcast(&(q->empty));
+ pthread_mutex_unlock(&(q->lock));
+}
+
+void * dequeue(Queue *q)
+{
+ Node *n, *nextNode;
+ void *data = NULL;
+
+ pthread_mutex_lock(&(q->lock));
+
+ if (!is_queue_empty(q)) {
+ n = q->front;
+ nextNode = q->front->next;
+ if (q->front == q->rear) {
+ q->rear = nextNode;
+ }
+ q->front = nextNode;
+ data = n->element;
+ free(n);
+ }
+ pthread_cond_broadcast(&(q->empty));
+ pthread_mutex_unlock(&(q->lock));
+ return data;
+}
+
+int is_queue_empty(Queue *q)
+{
+ return (q->front == NULL);
+}
+
+void destroy_queue(Queue **q)
+{
+ Node *n = NULL;
+ Node *next_n;
+
+ if (!q || !*q)
+ return;
+
+ for (n = (*q)->front; n != NULL ; n = next_n) {
+ next_n = n->next;
+ if((*q)->free_element)
+ (*q)->free_element(n->element);
+ free(n);
+ }
+
+ pthread_mutex_destroy(&((*q)->lock));
+ pthread_cond_destroy(&((*q)->empty));
+
+ free(*q);
+ *q = NULL;
+}
+