1/* 2 Copyright (c) 2010 Frank Lahm <franklahm@gmail.com> 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13*/ 14 15/*! 16 * @file 17 * Netatalk utility functions: queue 18 */ 19 20#ifdef HAVE_CONFIG_H 21#include "config.h" 22#endif /* HAVE_CONFIG_H */ 23 24#include <stdlib.h> 25 26#include <atalk/queue.h> 27 28static qnode_t *alloc_init_node(void *data) 29{ 30 qnode_t *node; 31 if ((node = malloc(sizeof(qnode_t))) == NULL) 32 return NULL; 33 node->data = data; 34 35 return node; 36} 37 38/******************************************************************************** 39 * Interface 40 *******************************************************************************/ 41 42q_t *queue_init(void) 43{ 44 q_t *queue; 45 46 if ((queue = alloc_init_node(NULL)) == NULL) 47 return NULL; 48 49 queue->prev = queue->next = queue; 50 return queue; 51} 52 53/* Insert at tail */ 54qnode_t *enqueue(q_t *q, void *data) 55{ 56 qnode_t *node; 57 58 if ((node = alloc_init_node(data)) == NULL) 59 return NULL; 60 61 /* insert at tail */ 62 node->next = q; 63 node->prev = q->prev; 64 q->prev->next = node; 65 q->prev = node; 66 67 return node; 68} 69 70/* Insert at head */ 71qnode_t *prequeue(q_t *q, void *data) 72{ 73 qnode_t *node; 74 75 if ((node = alloc_init_node(data)) == NULL) 76 return NULL; 77 78 /* insert at head */ 79 q->next->prev = node; 80 node->next = q->next; 81 node->prev = q; 82 q->next = node; 83 84 return node; 85} 86 87/* Take from head */ 88void *dequeue(q_t *q) 89{ 90 qnode_t *node; 91 void *data; 92 93 if (q == NULL || q->next == q) 94 return NULL; 95 96 /* take first node from head */ 97 node = q->next; 98 data = node->data; 99 q->next = node->next; 100 node->next->prev = node->prev; 101 free(node); 102 103 return data; 104} 105 106void queue_destroy(q_t *q, void (*callback)(void *)) 107{ 108 void *p; 109 110 while ((p = dequeue(q)) != NULL) 111 callback(p); 112 113 free(q); 114 q = NULL; 115} 116 117