include-afsconfig-before-param-h-20010712
[openafs.git] / src / bucoord / dlq.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID("$Header$");
14
15 #include <afs/bubasics.h>
16
17 #define DLQ_ASSERT_HEAD(headptr)                                \
18         if ( (headptr)->dlq_type != DLQ_HEAD )                  \
19         {                                                       \
20             printf("file %s line %d, invalid queue head\n",     \
21                    __FILE__, __LINE__);                         \
22             exit(1);                                            \
23         }
24
25
26 /* dlqEmpty
27  * exit:
28  *      1 - queue is empty
29  *      0 - items on queue
30  */
31
32 dlqEmpty(headptr)
33      dlqlinkP   headptr;
34 {
35     DLQ_ASSERT_HEAD(headptr);
36     if ( headptr->dlq_next == headptr )
37         return(1);
38     return(0);
39 }
40
41 dlqInit(headptr)
42      dlqlinkP   headptr;
43 {
44     headptr->dlq_next = headptr;
45     headptr->dlq_prev = headptr;
46     headptr->dlq_type = DLQ_HEAD;
47     headptr->dlq_structPtr = (char *)0;
48     return(0);
49 }
50
51 /* dlqLinkf
52  *      link item to front of chain
53  */
54 dlqLinkf(headptr, entryptr)
55      dlqlinkP   headptr;
56      dlqlinkP   entryptr;
57 {
58     DLQ_ASSERT_HEAD(headptr);
59     /* link in as first item in chain */
60     entryptr->dlq_next = headptr->dlq_next;
61     headptr->dlq_next->dlq_prev = entryptr;
62     entryptr->dlq_prev = headptr;
63     headptr->dlq_next = entryptr;
64     return(0);
65 }       
66
67 /* dlqLinkb
68  *      link item to end of chain
69  */
70
71 dlqLinkb(headptr, entryptr)
72      dlqlinkP   headptr;
73      dlqlinkP   entryptr;
74 {
75     DLQ_ASSERT_HEAD(headptr);
76     entryptr->dlq_next = headptr;
77     entryptr->dlq_prev = headptr->dlq_prev;
78
79     headptr->dlq_prev = entryptr;
80     entryptr->dlq_prev->dlq_next = entryptr;
81     return(0);
82 }
83
84 /* dlqMoveb
85  *      move all the items on the fromptr and append to the toptr's list
86  */
87
88 dlqMoveb(fromptr, toptr)
89      dlqlinkP   fromptr;
90      dlqlinkP   toptr;
91 {
92     dlqlinkP    tailptr;
93
94     DLQ_ASSERT_HEAD(fromptr);
95     DLQ_ASSERT_HEAD(toptr);
96
97     if ( dlqEmpty(fromptr) )
98         return(0);
99
100     tailptr = toptr->dlq_prev;
101
102     tailptr->dlq_next = fromptr->dlq_next;
103     tailptr->dlq_next->dlq_prev = tailptr;
104
105     /* now fix up the last item in the new chain */
106     tailptr = fromptr->dlq_prev;
107
108     tailptr->dlq_next = toptr;
109     toptr->dlq_prev = tailptr;
110
111     fromptr->dlq_next = fromptr;
112     fromptr->dlq_prev = fromptr;
113 }
114
115 /* dlqUnlinkb
116  *      unlink the last item on the queue
117  */
118
119 dlqlinkP
120 dlqUnlinkb(headptr) 
121      dlqlinkP   headptr;
122 {
123     dlqlinkP    ptr;
124     DLQ_ASSERT_HEAD(headptr);
125
126     if ( dlqEmpty(headptr) )
127         return(0);
128
129     ptr = headptr->dlq_prev;
130     ptr->dlq_prev->dlq_next = headptr;
131     headptr->dlq_prev = ptr->dlq_prev;
132     
133     ptr->dlq_next = ptr;
134     ptr->dlq_prev = ptr;
135     return(ptr);
136 }
137
138 /* dlqUnlinkf
139  *      unlink the item on the front of the queue
140  */
141
142 dlqlinkP
143 dlqUnlinkf(headptr)
144      dlqlinkP   headptr;
145 {
146     dlqlinkP    ptr;
147     DLQ_ASSERT_HEAD(headptr);
148
149     if ( dlqEmpty(headptr) )
150         return(0);
151
152     ptr = headptr->dlq_next;
153
154     headptr->dlq_next = ptr->dlq_next;
155     ptr->dlq_next->dlq_prev = headptr;
156
157     ptr->dlq_next = ptr;
158     ptr->dlq_prev = ptr;
159     return(ptr);
160 }
161
162 /* dlqUnlink
163  *      unlink the specified item from the queue.
164  */
165
166 dlqUnlink(ptr)
167      dlqlinkP    ptr;
168 {
169     /* must not be the queue head */
170     if ( ptr->dlq_type == DLQ_HEAD )
171     {
172         printf("dlqUnlink: invalid unlink\n");
173         exit(1);
174     }
175
176     ptr->dlq_prev->dlq_next = ptr->dlq_next;
177     ptr->dlq_next->dlq_prev = ptr->dlq_prev;
178
179     ptr->dlq_next = 0;
180     ptr->dlq_prev = 0;
181 }
182
183 /* dlqFront
184  *      return point to item at front of queuen
185  */
186
187 dlqlinkP
188 dlqFront(headptr)
189      dlqlinkP   headptr;
190 {
191     DLQ_ASSERT_HEAD(headptr);
192
193     if ( dlqEmpty(headptr) )
194         return(0);
195
196     return(headptr->dlq_next);
197 }
198
199 int
200 dlqCount(headptr)
201      dlqlinkP   headptr;
202 {
203     dlqlinkP    ptr;
204     int count = 0;
205
206     DLQ_ASSERT_HEAD(headptr);
207
208     ptr = headptr->dlq_next;
209     while ( ptr != headptr )
210     {
211         ptr = ptr->dlq_next;
212         count++;
213     }
214     return(count);
215 }
216
217 dlqTraverseQueue(headptr, fn1, fn2)
218      dlqlinkP   headptr;
219      int (*fn1)();
220      int (*fn2)();
221 {
222     dlqlinkP    ptr, oldPtr;
223
224     DLQ_ASSERT_HEAD(headptr);
225
226     ptr = headptr->dlq_next;
227     while ( ptr != headptr )
228     {
229         if (fn2 && ptr->dlq_structPtr)
230             (*fn2)(ptr->dlq_structPtr);
231         oldPtr = ptr;
232         ptr = ptr->dlq_next;
233         if (fn1) (*fn1)(oldPtr);
234     }
235     return(0);
236 }
237
238
239
240