Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / bucoord / dlq.c
CommitLineData
805e021f
CE
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/stds.h>
12
13#include <roken.h>
14
15#include "bc.h"
16#include <afs/bubasics.h>
17#include "bucoord_prototypes.h"
18
19/* protos */
20int dlqCount(dlqlinkP );
21void dlqMoveb( dlqlinkP, dlqlinkP);
22dlqlinkP dlqUnlinkb(dlqlinkP );
23dlqlinkP dlqUnlinkf(dlqlinkP );
24dlqlinkP dlqFront(dlqlinkP headptr);
25
26#define DLQ_ASSERT_HEAD(headptr) \
27 if ( (headptr)->dlq_type != DLQ_HEAD ) \
28 { \
29 printf("file %s line %d, invalid queue head\n", \
30 __FILE__, __LINE__); \
31 exit(1); \
32 }
33
34
35/* dlqEmpty
36 * exit:
37 * 1 - queue is empty
38 * 0 - items on queue
39 */
40
41int dlqEmpty(dlqlinkP headptr )
42{
43 DLQ_ASSERT_HEAD(headptr);
44 if (headptr->dlq_next == headptr)
45 return (1);
46 return (0);
47}
48
49int dlqInit(dlqlinkP headptr)
50{
51 headptr->dlq_next = headptr;
52 headptr->dlq_prev = headptr;
53 headptr->dlq_type = DLQ_HEAD;
54 headptr->dlq_structPtr = NULL;
55 return (0);
56}
57
58/* dlqLinkf
59 * link item to front of chain
60 */
61int dlqLinkf(dlqlinkP headptr, dlqlinkP entryptr)
62{
63 DLQ_ASSERT_HEAD(headptr);
64 /* link in as first item in chain */
65 entryptr->dlq_next = headptr->dlq_next;
66 headptr->dlq_next->dlq_prev = entryptr;
67 entryptr->dlq_prev = headptr;
68 headptr->dlq_next = entryptr;
69 return (0);
70}
71
72/* dlqLinkb
73 * link item to end of chain
74 */
75
76int dlqLinkb(dlqlinkP headptr, dlqlinkP entryptr)
77{
78 DLQ_ASSERT_HEAD(headptr);
79 entryptr->dlq_next = headptr;
80 entryptr->dlq_prev = headptr->dlq_prev;
81
82 headptr->dlq_prev = entryptr;
83 entryptr->dlq_prev->dlq_next = entryptr;
84 return (0);
85}
86
87/* dlqMoveb
88 * move all the items on the fromptr and append to the toptr's list
89 */
90
91void dlqMoveb( dlqlinkP fromptr, dlqlinkP toptr)
92{
93 dlqlinkP tailptr;
94
95 DLQ_ASSERT_HEAD(fromptr);
96 DLQ_ASSERT_HEAD(toptr);
97
98 if (dlqEmpty(fromptr))
99 return;
100
101 tailptr = toptr->dlq_prev;
102
103 tailptr->dlq_next = fromptr->dlq_next;
104 tailptr->dlq_next->dlq_prev = tailptr;
105
106 /* now fix up the last item in the new chain */
107 tailptr = fromptr->dlq_prev;
108
109 tailptr->dlq_next = toptr;
110 toptr->dlq_prev = tailptr;
111
112 fromptr->dlq_next = fromptr;
113 fromptr->dlq_prev = fromptr;
114 return;
115}
116
117/* dlqUnlinkb
118 * unlink the last item on the queue
119 */
120
121dlqlinkP dlqUnlinkb(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
142dlqlinkP dlqUnlinkf(dlqlinkP headptr)
143{
144 dlqlinkP ptr;
145 DLQ_ASSERT_HEAD(headptr);
146
147 if (dlqEmpty(headptr))
148 return (0);
149
150 ptr = headptr->dlq_next;
151
152 headptr->dlq_next = ptr->dlq_next;
153 ptr->dlq_next->dlq_prev = headptr;
154
155 ptr->dlq_next = ptr;
156 ptr->dlq_prev = ptr;
157 return (ptr);
158}
159
160/* dlqUnlink
161 * unlink the specified item from the queue.
162 */
163
164void dlqUnlink( dlqlinkP ptr)
165{
166 /* must not be the queue head */
167 if (ptr->dlq_type == DLQ_HEAD) {
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
183dlqlinkP dlqFront(dlqlinkP headptr)
184{
185 DLQ_ASSERT_HEAD(headptr);
186
187 if (dlqEmpty(headptr))
188 return (0);
189
190 return (headptr->dlq_next);
191}
192
193int dlqCount(dlqlinkP headptr)
194{
195 dlqlinkP ptr;
196 int count = 0;
197
198 DLQ_ASSERT_HEAD(headptr);
199
200 ptr = headptr->dlq_next;
201 while (ptr != headptr) {
202 ptr = ptr->dlq_next;
203 count++;
204 }
205 return (count);
206}
207
208int dlqTraverseQueue(dlqlinkP headptr, int (*fn1)(void *), int (*fn2)(void *))
209{
210 dlqlinkP ptr, oldPtr;
211
212 DLQ_ASSERT_HEAD(headptr);
213
214 ptr = headptr->dlq_next;
215 while (ptr != headptr) {
216 if (fn2 && ptr->dlq_structPtr)
217 (*fn2) (ptr->dlq_structPtr);
218 oldPtr = ptr;
219 ptr = ptr->dlq_next;
220 if (fn1)
221 (*fn1) (oldPtr);
222 }
223 return (0);
224}