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