diff options
Diffstat (limited to 'tacplus-daemon/queue.c')
-rw-r--r-- | tacplus-daemon/queue.c | 127 |
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; +} + |