1*54925bf6Swillf /*
2*54925bf6Swillf  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
3*54925bf6Swillf  * Use is subject to license terms.
4*54925bf6Swillf  */
5*54925bf6Swillf 
6*54925bf6Swillf #ifndef _KRB5_DB2_DBQUEUE_H
7*54925bf6Swillf #define	_KRB5_DB2_DBQUEUE_H
8*54925bf6Swillf 
9*54925bf6Swillf #ifdef	__cplusplus
10*54925bf6Swillf extern "C" {
11*54925bf6Swillf #endif
12*54925bf6Swillf 
13*54925bf6Swillf /*
14*54925bf6Swillf  * Copyright (c) 1991, 1993
15*54925bf6Swillf  *	The Regents of the University of California.  All rights reserved.
16*54925bf6Swillf  *
17*54925bf6Swillf  * Redistribution and use in source and binary forms, with or without
18*54925bf6Swillf  * modification, are permitted provided that the following conditions
19*54925bf6Swillf  * are met:
20*54925bf6Swillf  * 1. Redistributions of source code must retain the above copyright
21*54925bf6Swillf  *    notice, this list of conditions and the following disclaimer.
22*54925bf6Swillf  * 2. Redistributions in binary form must reproduce the above copyright
23*54925bf6Swillf  *    notice, this list of conditions and the following disclaimer in the
24*54925bf6Swillf  *    documentation and/or other materials provided with the distribution.
25*54925bf6Swillf  * 3. All advertising materials mentioning features or use of this software
26*54925bf6Swillf  *    must display the following acknowledgement:
27*54925bf6Swillf  *	This product includes software developed by the University of
28*54925bf6Swillf  *	California, Berkeley and its contributors.
29*54925bf6Swillf  * 4. Neither the name of the University nor the names of its contributors
30*54925bf6Swillf  *    may be used to endorse or promote products derived from this software
31*54925bf6Swillf  *    without specific prior written permission.
32*54925bf6Swillf  *
33*54925bf6Swillf  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34*54925bf6Swillf  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35*54925bf6Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36*54925bf6Swillf  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37*54925bf6Swillf  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38*54925bf6Swillf  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39*54925bf6Swillf  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40*54925bf6Swillf  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41*54925bf6Swillf  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42*54925bf6Swillf  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43*54925bf6Swillf  * SUCH DAMAGE.
44*54925bf6Swillf  *
45*54925bf6Swillf  *	@(#)queue.h	8.3 (Berkeley) 12/13/93
46*54925bf6Swillf  */
47*54925bf6Swillf 
48*54925bf6Swillf #ifndef	_QUEUE_H_
49*54925bf6Swillf #define	_QUEUE_H_
50*54925bf6Swillf 
51*54925bf6Swillf /*
52*54925bf6Swillf  * This file defines three types of data structures: lists, tail queues,
53*54925bf6Swillf  * and circular queues.
54*54925bf6Swillf  *
55*54925bf6Swillf  * A list is headed by a single forward pointer (or an array of forward
56*54925bf6Swillf  * pointers for a hash table header). The elements are doubly linked
57*54925bf6Swillf  * so that an arbitrary element can be removed without a need to
58*54925bf6Swillf  * traverse the list. New elements can be added to the list after
59*54925bf6Swillf  * an existing element or at the head of the list. A list may only be
60*54925bf6Swillf  * traversed in the forward direction.
61*54925bf6Swillf  *
62*54925bf6Swillf  * A tail queue is headed by a pair of pointers, one to the head of the
63*54925bf6Swillf  * list and the other to the tail of the list. The elements are doubly
64*54925bf6Swillf  * linked so that an arbitrary element can be removed without a need to
65*54925bf6Swillf  * traverse the list. New elements can be added to the list after
66*54925bf6Swillf  * an existing element, at the head of the list, or at the end of the
67*54925bf6Swillf  * list. A tail queue may only be traversed in the forward direction.
68*54925bf6Swillf  *
69*54925bf6Swillf  * A circle queue is headed by a pair of pointers, one to the head of the
70*54925bf6Swillf  * list and the other to the tail of the list. The elements are doubly
71*54925bf6Swillf  * linked so that an arbitrary element can be removed without a need to
72*54925bf6Swillf  * traverse the list. New elements can be added to the list before or after
73*54925bf6Swillf  * an existing element, at the head of the list, or at the end of the list.
74*54925bf6Swillf  * A circle queue may be traversed in either direction, but has a more
75*54925bf6Swillf  * complex end of list detection.
76*54925bf6Swillf  *
77*54925bf6Swillf  * For details on the use of these macros, see the queue(3) manual page.
78*54925bf6Swillf  */
79*54925bf6Swillf 
80*54925bf6Swillf /*
81*54925bf6Swillf  * List definitions.
82*54925bf6Swillf  */
83*54925bf6Swillf #define LIST_HEAD(name, type)						\
84*54925bf6Swillf struct name {								\
85*54925bf6Swillf 	struct type *lh_first;	/* first element */			\
86*54925bf6Swillf }
87*54925bf6Swillf 
88*54925bf6Swillf #define LIST_ENTRY(type)						\
89*54925bf6Swillf struct {								\
90*54925bf6Swillf 	struct type *le_next;	/* next element */			\
91*54925bf6Swillf 	struct type **le_prev;	/* address of previous next element */	\
92*54925bf6Swillf }
93*54925bf6Swillf 
94*54925bf6Swillf /*
95*54925bf6Swillf  * List functions.
96*54925bf6Swillf  */
97*54925bf6Swillf #define	LIST_INIT(head) {						\
98*54925bf6Swillf 	(head)->lh_first = NULL;					\
99*54925bf6Swillf }
100*54925bf6Swillf 
101*54925bf6Swillf #define LIST_INSERT_AFTER(listelm, elm, field) {			\
102*54925bf6Swillf 	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
103*54925bf6Swillf 		(listelm)->field.le_next->field.le_prev =		\
104*54925bf6Swillf 		    &(elm)->field.le_next;				\
105*54925bf6Swillf 	(listelm)->field.le_next = (elm);				\
106*54925bf6Swillf 	(elm)->field.le_prev = &(listelm)->field.le_next;		\
107*54925bf6Swillf }
108*54925bf6Swillf 
109*54925bf6Swillf #define LIST_INSERT_HEAD(head, elm, field) {				\
110*54925bf6Swillf 	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
111*54925bf6Swillf 		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
112*54925bf6Swillf 	(head)->lh_first = (elm);					\
113*54925bf6Swillf 	(elm)->field.le_prev = &(head)->lh_first;			\
114*54925bf6Swillf }
115*54925bf6Swillf 
116*54925bf6Swillf #define LIST_REMOVE(elm, field) {					\
117*54925bf6Swillf 	if ((elm)->field.le_next != NULL)				\
118*54925bf6Swillf 		(elm)->field.le_next->field.le_prev = 			\
119*54925bf6Swillf 		    (elm)->field.le_prev;				\
120*54925bf6Swillf 	*(elm)->field.le_prev = (elm)->field.le_next;			\
121*54925bf6Swillf }
122*54925bf6Swillf 
123*54925bf6Swillf /*
124*54925bf6Swillf  * Tail queue definitions.
125*54925bf6Swillf  */
126*54925bf6Swillf #define TAILQ_HEAD(name, type)						\
127*54925bf6Swillf struct name {								\
128*54925bf6Swillf 	struct type *tqh_first;	/* first element */			\
129*54925bf6Swillf 	struct type **tqh_last;	/* addr of last next element */		\
130*54925bf6Swillf }
131*54925bf6Swillf 
132*54925bf6Swillf #define TAILQ_ENTRY(type)						\
133*54925bf6Swillf struct {								\
134*54925bf6Swillf 	struct type *tqe_next;	/* next element */			\
135*54925bf6Swillf 	struct type **tqe_prev;	/* address of previous next element */	\
136*54925bf6Swillf }
137*54925bf6Swillf 
138*54925bf6Swillf /*
139*54925bf6Swillf  * Tail queue functions.
140*54925bf6Swillf  */
141*54925bf6Swillf #define	TAILQ_INIT(head) {						\
142*54925bf6Swillf 	(head)->tqh_first = NULL;					\
143*54925bf6Swillf 	(head)->tqh_last = &(head)->tqh_first;				\
144*54925bf6Swillf }
145*54925bf6Swillf 
146*54925bf6Swillf #define TAILQ_INSERT_HEAD(head, elm, field) {				\
147*54925bf6Swillf 	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
148*54925bf6Swillf 		(elm)->field.tqe_next->field.tqe_prev =			\
149*54925bf6Swillf 		    &(elm)->field.tqe_next;				\
150*54925bf6Swillf 	else								\
151*54925bf6Swillf 		(head)->tqh_last = &(elm)->field.tqe_next;		\
152*54925bf6Swillf 	(head)->tqh_first = (elm);					\
153*54925bf6Swillf 	(elm)->field.tqe_prev = &(head)->tqh_first;			\
154*54925bf6Swillf }
155*54925bf6Swillf 
156*54925bf6Swillf #define TAILQ_INSERT_TAIL(head, elm, field) {				\
157*54925bf6Swillf 	(elm)->field.tqe_next = NULL;					\
158*54925bf6Swillf 	(elm)->field.tqe_prev = (head)->tqh_last;			\
159*54925bf6Swillf 	*(head)->tqh_last = (elm);					\
160*54925bf6Swillf 	(head)->tqh_last = &(elm)->field.tqe_next;			\
161*54925bf6Swillf }
162*54925bf6Swillf 
163*54925bf6Swillf #define TAILQ_INSERT_AFTER(head, listelm, elm, field) {			\
164*54925bf6Swillf 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
165*54925bf6Swillf 		(elm)->field.tqe_next->field.tqe_prev = 		\
166*54925bf6Swillf 		    &(elm)->field.tqe_next;				\
167*54925bf6Swillf 	else								\
168*54925bf6Swillf 		(head)->tqh_last = &(elm)->field.tqe_next;		\
169*54925bf6Swillf 	(listelm)->field.tqe_next = (elm);				\
170*54925bf6Swillf 	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
171*54925bf6Swillf }
172*54925bf6Swillf 
173*54925bf6Swillf #define TAILQ_REMOVE(head, elm, field) {				\
174*54925bf6Swillf 	if (((elm)->field.tqe_next) != NULL)				\
175*54925bf6Swillf 		(elm)->field.tqe_next->field.tqe_prev = 		\
176*54925bf6Swillf 		    (elm)->field.tqe_prev;				\
177*54925bf6Swillf 	else								\
178*54925bf6Swillf 		(head)->tqh_last = (elm)->field.tqe_prev;		\
179*54925bf6Swillf 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
180*54925bf6Swillf }
181*54925bf6Swillf 
182*54925bf6Swillf /*
183*54925bf6Swillf  * Circular queue definitions.
184*54925bf6Swillf  */
185*54925bf6Swillf #define CIRCLEQ_HEAD(name, type)					\
186*54925bf6Swillf struct name {								\
187*54925bf6Swillf 	struct type *cqh_first;		/* first element */		\
188*54925bf6Swillf 	struct type *cqh_last;		/* last element */		\
189*54925bf6Swillf }
190*54925bf6Swillf 
191*54925bf6Swillf #define CIRCLEQ_ENTRY(type)						\
192*54925bf6Swillf struct {								\
193*54925bf6Swillf 	struct type *cqe_next;		/* next element */		\
194*54925bf6Swillf 	struct type *cqe_prev;		/* previous element */		\
195*54925bf6Swillf }
196*54925bf6Swillf 
197*54925bf6Swillf /*
198*54925bf6Swillf  * Circular queue functions.
199*54925bf6Swillf  */
200*54925bf6Swillf #define	CIRCLEQ_INIT(head) {						\
201*54925bf6Swillf 	(head)->cqh_first = (void *)(head);				\
202*54925bf6Swillf 	(head)->cqh_last = (void *)(head);				\
203*54925bf6Swillf }
204*54925bf6Swillf 
205*54925bf6Swillf #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) {		\
206*54925bf6Swillf 	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
207*54925bf6Swillf 	(elm)->field.cqe_prev = (listelm);				\
208*54925bf6Swillf 	if ((listelm)->field.cqe_next == (void *)(head))		\
209*54925bf6Swillf 		(head)->cqh_last = (elm);				\
210*54925bf6Swillf 	else								\
211*54925bf6Swillf 		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
212*54925bf6Swillf 	(listelm)->field.cqe_next = (elm);				\
213*54925bf6Swillf }
214*54925bf6Swillf 
215*54925bf6Swillf #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) {		\
216*54925bf6Swillf 	(elm)->field.cqe_next = (listelm);				\
217*54925bf6Swillf 	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
218*54925bf6Swillf 	if ((listelm)->field.cqe_prev == (void *)(head))		\
219*54925bf6Swillf 		(head)->cqh_first = (elm);				\
220*54925bf6Swillf 	else								\
221*54925bf6Swillf 		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
222*54925bf6Swillf 	(listelm)->field.cqe_prev = (elm);				\
223*54925bf6Swillf }
224*54925bf6Swillf 
225*54925bf6Swillf #define CIRCLEQ_INSERT_HEAD(head, elm, field) {				\
226*54925bf6Swillf 	(elm)->field.cqe_next = (head)->cqh_first;			\
227*54925bf6Swillf 	(elm)->field.cqe_prev = (void *)(head);				\
228*54925bf6Swillf 	if ((head)->cqh_last == (void *)(head))				\
229*54925bf6Swillf 		(head)->cqh_last = (elm);				\
230*54925bf6Swillf 	else								\
231*54925bf6Swillf 		(head)->cqh_first->field.cqe_prev = (elm);		\
232*54925bf6Swillf 	(head)->cqh_first = (elm);					\
233*54925bf6Swillf }
234*54925bf6Swillf 
235*54925bf6Swillf #define CIRCLEQ_INSERT_TAIL(head, elm, field) {				\
236*54925bf6Swillf 	(elm)->field.cqe_next = (void *)(head);				\
237*54925bf6Swillf 	(elm)->field.cqe_prev = (head)->cqh_last;			\
238*54925bf6Swillf 	if ((head)->cqh_first == (void *)(head))			\
239*54925bf6Swillf 		(head)->cqh_first = (elm);				\
240*54925bf6Swillf 	else								\
241*54925bf6Swillf 		(head)->cqh_last->field.cqe_next = (elm);		\
242*54925bf6Swillf 	(head)->cqh_last = (elm);					\
243*54925bf6Swillf }
244*54925bf6Swillf 
245*54925bf6Swillf #define	CIRCLEQ_REMOVE(head, elm, field) {				\
246*54925bf6Swillf 	if ((elm)->field.cqe_next == (void *)(head))			\
247*54925bf6Swillf 		(head)->cqh_last = (elm)->field.cqe_prev;		\
248*54925bf6Swillf 	else								\
249*54925bf6Swillf 		(elm)->field.cqe_next->field.cqe_prev =			\
250*54925bf6Swillf 		    (elm)->field.cqe_prev;				\
251*54925bf6Swillf 	if ((elm)->field.cqe_prev == (void *)(head))			\
252*54925bf6Swillf 		(head)->cqh_first = (elm)->field.cqe_next;		\
253*54925bf6Swillf 	else								\
254*54925bf6Swillf 		(elm)->field.cqe_prev->field.cqe_next =			\
255*54925bf6Swillf 		    (elm)->field.cqe_next;				\
256*54925bf6Swillf }
257*54925bf6Swillf #endif	/* !_QUEUE_H_ */
258*54925bf6Swillf 
259*54925bf6Swillf #ifdef	__cplusplus
260*54925bf6Swillf }
261*54925bf6Swillf #endif
262*54925bf6Swillf 
263*54925bf6Swillf #endif	/* !_KRB5_DB2_DBQUEUE_H */
264