]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/queue.c
Initial revision
[bacula/bacula] / bacula / src / lib / queue.c
1 /*
2
3                          Q U E U E
4                      Queue Handling Routines
5
6         Taken from smartall by John Walker.
7
8                   http://www.fourmilab.ch/smartall/
9
10 */
11
12 /*
13    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
14
15    This program is free software; you can redistribute it and/or
16    modify it under the terms of the GNU General Public License as
17    published by the Free Software Foundation; either version 2 of
18    the License, or (at your option) any later version.
19
20    This program is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23    General Public License for more details.
24
25    You should have received a copy of the GNU General Public
26    License along with this program; if not, write to the Free
27    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
28    MA 02111-1307, USA.
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 }