]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/queue.c
Backport from Bacula Enterprise
[bacula/bacula] / bacula / src / lib / queue.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6
7    The original author of Bacula is Kern Sibbald, with contributions
8    from many others, a complete list can be found in the file AUTHORS.
9
10    You may use this file and others of this release according to the
11    license defined in the LICENSE file, which includes the Affero General
12    Public License, v3.0 ("AGPLv3") and some additional permissions and
13    terms pursuant to its AGPLv3 Section 7.
14
15    This notice must be preserved when any source code is 
16    conveyed and/or propagated.
17
18    Bacula(R) is a registered trademark of Kern Sibbald.
19 */
20 /*
21
22                          Q U E U E
23                      Queue Handling Routines
24
25         Taken from smartall written by John Walker.
26
27                   http://www.fourmilab.ch/smartall/
28
29
30
31 */
32
33 #include "bacula.h"
34
35 /*  General purpose queue  */
36
37 #ifdef REALLY_NEEDED
38 struct b_queue {
39         struct b_queue *qnext,       /* Next item in queue */
40                      *qprev;       /* Previous item in queue */
41 };
42 #endif
43
44 /*
45  * To define a queue, use the following
46  *
47  *  static BQUEUE xyz = { &xyz, &xyz };
48  *
49  *   Also, note, that the only real requirement is that
50  *   the object that is passed to these routines contain
51  *   a BQUEUE object as the very first member. The
52  *   rest of the structure may be anything.
53  *
54  *   NOTE!!!! The casting here is REALLY painful, but this avoids
55  *            doing ugly casting every where else in the code.
56  */
57
58
59 /*  Queue manipulation functions.  */
60
61
62 /*  QINSERT  --  Insert object at end of queue  */
63
64 void qinsert(BQUEUE *qhead, BQUEUE *object)
65 {
66 #define qh ((BQUEUE *)qhead)
67 #define obj ((BQUEUE *)object)
68
69         ASSERT(qh->qprev->qnext == qh);
70         ASSERT(qh->qnext->qprev == qh);
71
72         obj->qnext = qh;
73         obj->qprev = qh->qprev;
74         qh->qprev = obj;
75         obj->qprev->qnext = obj;
76 #undef qh
77 #undef obj
78 }
79
80
81 /*  QREMOVE  --  Remove next object from the queue given
82                  the queue head (or any item).
83      Returns NULL if queue is empty  */
84
85 BQUEUE *qremove(BQUEUE *qhead)
86 {
87 #define qh ((BQUEUE *)qhead)
88         BQUEUE *object;
89
90         ASSERT(qh->qprev->qnext == qh);
91         ASSERT(qh->qnext->qprev == qh);
92
93         if ((object = qh->qnext) == qh)
94            return NULL;
95         qh->qnext = object->qnext;
96         object->qnext->qprev = qh;
97         return object;
98 #undef qh
99 }
100
101 /*  QNEXT   --   Return next item from the queue
102  *               returns NULL at the end of the queue.
103  *               If qitem is NULL, the first item from
104  *               the queue is returned.
105  */
106
107 BQUEUE *qnext(BQUEUE *qhead, BQUEUE *qitem)
108 {
109 #define qh ((BQUEUE *)qhead)
110 #define qi ((BQUEUE *)qitem)
111
112         BQUEUE *object;
113
114         if (qi == NULL)
115            qitem = qhead;
116         ASSERT(qi->qprev->qnext == qi);
117         ASSERT(qi->qnext->qprev == qi);
118
119         if ((object = qi->qnext) == qh)
120            return NULL;
121         return object;
122 #undef qh
123 #undef qi
124 }
125
126
127 /*  QDCHAIN  --  Dequeue an item from the middle of a queue.  Passed
128                  the queue item, returns the (now dechained) queue item. */
129
130 BQUEUE *qdchain(BQUEUE *qitem)
131 {
132 #define qi ((BQUEUE *)qitem)
133
134         ASSERT(qi->qprev->qnext == qi);
135         ASSERT(qi->qnext->qprev == qi);
136
137         return qremove(qi->qprev);
138 #undef qi
139 }