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