]> arthur.barton.de Git - netatalk.git/blob - libatalk/util/queue.c
Merge 2-1
[netatalk.git] / libatalk / util / queue.c
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
28 static 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
42 q_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 */
54 qnode_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 */
71 qnode_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 */
88 void *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
106 void 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