1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2251875Speter * contributor license agreements.  See the NOTICE file distributed with
3251875Speter * this work for additional information regarding copyright ownership.
4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5251875Speter * (the "License"); you may not use this file except in compliance with
6251875Speter * the License.  You may obtain a copy of the License at
7251875Speter *
8251875Speter *     http://www.apache.org/licenses/LICENSE-2.0
9251875Speter *
10251875Speter * Unless required by applicable law or agreed to in writing, software
11251875Speter * distributed under the License is distributed on an "AS IS" BASIS,
12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13251875Speter * See the License for the specific language governing permissions and
14251875Speter * limitations under the License.
15251875Speter */
16251875Speter
17251875Speter/*
18251875Speter * This code draws heavily from the 4.4BSD <sys/queue.h> macros
19251875Speter * and Dean Gaudet's "splim/ring.h".
20251875Speter * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h>
21251875Speter * <http://www.arctic.org/~dean/splim/>
22251875Speter *
23251875Speter * We'd use Dean's code directly if we could guarantee the
24251875Speter * availability of inline functions.
25251875Speter */
26251875Speter
27251875Speter#ifndef APR_RING_H
28251875Speter#define APR_RING_H
29251875Speter
30251875Speter/**
31251875Speter * @file apr_ring.h
32251875Speter * @brief APR Rings
33251875Speter */
34251875Speter
35251875Speter/*
36251875Speter * for offsetof()
37251875Speter */
38251875Speter#include "apr_general.h"
39251875Speter
40251875Speter/**
41251875Speter * @defgroup apr_ring Ring Macro Implementations
42251875Speter * @ingroup APR
43251875Speter * A ring is a kind of doubly-linked list that can be manipulated
44251875Speter * without knowing where its head is.
45251875Speter * @{
46251875Speter */
47251875Speter
48251875Speter/**
49251875Speter * The Ring Element
50251875Speter *
51251875Speter * A ring element struct is linked to the other elements in the ring
52251875Speter * through its ring entry field, e.g.
53251875Speter * <pre>
54251875Speter *      struct my_element_t {
55251875Speter *          APR_RING_ENTRY(my_element_t) link;
56251875Speter *          int foo;
57251875Speter *          char *bar;
58251875Speter *      };
59251875Speter * </pre>
60251875Speter *
61251875Speter * An element struct may be put on more than one ring if it has more
62251875Speter * than one APR_RING_ENTRY field. Each APR_RING_ENTRY has a corresponding
63251875Speter * APR_RING_HEAD declaration.
64251875Speter *
65251875Speter * @warning For strict C standards compliance you should put the APR_RING_ENTRY
66251875Speter * first in the element struct unless the head is always part of a larger
67251875Speter * object with enough earlier fields to accommodate the offsetof() used
68251875Speter * to compute the ring sentinel below. You can usually ignore this caveat.
69251875Speter */
70251875Speter#define APR_RING_ENTRY(elem)						\
71251875Speter    struct {								\
72251875Speter	struct elem * volatile next;					\
73251875Speter	struct elem * volatile prev;					\
74251875Speter    }
75251875Speter
76251875Speter/**
77251875Speter * The Ring Head
78251875Speter *
79251875Speter * Each ring is managed via its head, which is a struct declared like this:
80251875Speter * <pre>
81251875Speter *      APR_RING_HEAD(my_ring_t, my_element_t);
82251875Speter *      struct my_ring_t ring, *ringp;
83251875Speter * </pre>
84251875Speter *
85251875Speter * This struct looks just like the element link struct so that we can
86251875Speter * be sure that the typecasting games will work as expected.
87251875Speter *
88251875Speter * The first element in the ring is next after the head, and the last
89251875Speter * element is just before the head.
90251875Speter */
91251875Speter#define APR_RING_HEAD(head, elem)					\
92251875Speter    struct head {							\
93251875Speter	struct elem * volatile next;					\
94251875Speter	struct elem * volatile prev;					\
95251875Speter    }
96251875Speter
97251875Speter/**
98251875Speter * The Ring Sentinel
99251875Speter *
100251875Speter * This is the magic pointer value that occurs before the first and
101251875Speter * after the last elements in the ring, computed from the address of
102251875Speter * the ring's head.  The head itself isn't an element, but in order to
103251875Speter * get rid of all the special cases when dealing with the ends of the
104251875Speter * ring, we play typecasting games to make it look like one.
105251875Speter *
106251875Speter * Here is a diagram to illustrate the arrangements of the next and
107251875Speter * prev pointers of each element in a single ring. Note that they point
108251875Speter * to the start of each element, not to the APR_RING_ENTRY structure.
109251875Speter *
110251875Speter * <pre>
111251875Speter *     +->+------+<-+  +->+------+<-+  +->+------+<-+
112251875Speter *     |  |struct|  |  |  |struct|  |  |  |struct|  |
113251875Speter *    /   | elem |   \/   | elem |   \/   | elem |  \
114251875Speter * ...    |      |   /\   |      |   /\   |      |   ...
115251875Speter *        +------+  |  |  +------+  |  |  +------+
116251875Speter *   ...--|prev  |  |  +--|ring  |  |  +--|prev  |
117251875Speter *        |  next|--+     | entry|--+     |  next|--...
118251875Speter *        +------+        +------+        +------+
119251875Speter *        | etc. |        | etc. |        | etc. |
120251875Speter *        :      :        :      :        :      :
121251875Speter * </pre>
122251875Speter *
123251875Speter * The APR_RING_HEAD is nothing but a bare APR_RING_ENTRY. The prev
124251875Speter * and next pointers in the first and last elements don't actually
125251875Speter * point to the head, they point to a phantom place called the
126251875Speter * sentinel. Its value is such that last->next->next == first because
127251875Speter * the offset from the sentinel to the head's next pointer is the same
128251875Speter * as the offset from the start of an element to its next pointer.
129251875Speter * This also works in the opposite direction.
130251875Speter *
131251875Speter * <pre>
132251875Speter *        last                            first
133251875Speter *     +->+------+<-+  +->sentinel<-+  +->+------+<-+
134251875Speter *     |  |struct|  |  |            |  |  |struct|  |
135251875Speter *    /   | elem |   \/              \/   | elem |  \
136251875Speter * ...    |      |   /\              /\   |      |   ...
137251875Speter *        +------+  |  |  +------+  |  |  +------+
138251875Speter *   ...--|prev  |  |  +--|ring  |  |  +--|prev  |
139251875Speter *        |  next|--+     |  head|--+     |  next|--...
140251875Speter *        +------+        +------+        +------+
141251875Speter *        | etc. |                        | etc. |
142251875Speter *        :      :                        :      :
143251875Speter * </pre>
144251875Speter *
145251875Speter * Note that the offset mentioned above is different for each kind of
146251875Speter * ring that the element may be on, and each kind of ring has a unique
147251875Speter * name for its APR_RING_ENTRY in each element, and has its own type
148251875Speter * for its APR_RING_HEAD.
149251875Speter *
150251875Speter * Note also that if the offset is non-zero (which is required if an
151251875Speter * element has more than one APR_RING_ENTRY), the unreality of the
152251875Speter * sentinel may have bad implications on very perverse implementations
153251875Speter * of C -- see the warning in APR_RING_ENTRY.
154251875Speter *
155251875Speter * @param hp   The head of the ring
156251875Speter * @param elem The name of the element struct
157251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
158251875Speter */
159251875Speter#define APR_RING_SENTINEL(hp, elem, link)				\
160251875Speter    (struct elem *)((char *)(&(hp)->next) - APR_OFFSETOF(struct elem, link))
161251875Speter
162251875Speter/**
163251875Speter * The first element of the ring
164251875Speter * @param hp   The head of the ring
165251875Speter */
166251875Speter#define APR_RING_FIRST(hp)	(hp)->next
167251875Speter/**
168251875Speter * The last element of the ring
169251875Speter * @param hp   The head of the ring
170251875Speter */
171251875Speter#define APR_RING_LAST(hp)	(hp)->prev
172251875Speter/**
173251875Speter * The next element in the ring
174251875Speter * @param ep   The current element
175251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
176251875Speter */
177251875Speter#define APR_RING_NEXT(ep, link)	(ep)->link.next
178251875Speter/**
179251875Speter * The previous element in the ring
180251875Speter * @param ep   The current element
181251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
182251875Speter */
183251875Speter#define APR_RING_PREV(ep, link)	(ep)->link.prev
184251875Speter
185251875Speter
186251875Speter/**
187251875Speter * Initialize a ring
188251875Speter * @param hp   The head of the ring
189251875Speter * @param elem The name of the element struct
190251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
191251875Speter */
192251875Speter#define APR_RING_INIT(hp, elem, link) do {				\
193251875Speter	APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link);	\
194251875Speter	APR_RING_LAST((hp))  = APR_RING_SENTINEL((hp), elem, link);	\
195251875Speter    } while (0)
196251875Speter
197251875Speter/**
198251875Speter * Determine if a ring is empty
199251875Speter * @param hp   The head of the ring
200251875Speter * @param elem The name of the element struct
201251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
202251875Speter * @return true or false
203251875Speter */
204251875Speter#define APR_RING_EMPTY(hp, elem, link)					\
205251875Speter    (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))
206251875Speter
207251875Speter/**
208251875Speter * Initialize a singleton element
209251875Speter * @param ep   The element
210251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
211251875Speter */
212251875Speter#define APR_RING_ELEM_INIT(ep, link) do {				\
213251875Speter	APR_RING_NEXT((ep), link) = (ep);				\
214251875Speter	APR_RING_PREV((ep), link) = (ep);				\
215251875Speter    } while (0)
216251875Speter
217251875Speter
218251875Speter/**
219251875Speter * Splice the sequence ep1..epN into the ring before element lep
220251875Speter *   (..lep.. becomes ..ep1..epN..lep..)
221251875Speter * @warning This doesn't work for splicing before the first element or on
222251875Speter *   empty rings... see APR_RING_SPLICE_HEAD for one that does
223251875Speter * @param lep  Element in the ring to splice before
224251875Speter * @param ep1  First element in the sequence to splice in
225251875Speter * @param epN  Last element in the sequence to splice in
226251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
227251875Speter */
228251875Speter#define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do {		\
229251875Speter	APR_RING_NEXT((epN), link) = (lep);				\
230251875Speter	APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link);	\
231251875Speter	APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1);	\
232251875Speter	APR_RING_PREV((lep), link) = (epN);				\
233251875Speter    } while (0)
234251875Speter
235251875Speter/**
236251875Speter * Splice the sequence ep1..epN into the ring after element lep
237251875Speter *   (..lep.. becomes ..lep..ep1..epN..)
238251875Speter * @warning This doesn't work for splicing after the last element or on
239251875Speter *   empty rings... see APR_RING_SPLICE_TAIL for one that does
240251875Speter * @param lep  Element in the ring to splice after
241251875Speter * @param ep1  First element in the sequence to splice in
242251875Speter * @param epN  Last element in the sequence to splice in
243251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
244251875Speter */
245251875Speter#define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do {			\
246251875Speter	APR_RING_PREV((ep1), link) = (lep);				\
247251875Speter	APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link);	\
248251875Speter	APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN);	\
249251875Speter	APR_RING_NEXT((lep), link) = (ep1);				\
250251875Speter    } while (0)
251251875Speter
252251875Speter/**
253251875Speter * Insert the element nep into the ring before element lep
254251875Speter *   (..lep.. becomes ..nep..lep..)
255251875Speter * @warning This doesn't work for inserting before the first element or on
256251875Speter *   empty rings... see APR_RING_INSERT_HEAD for one that does
257251875Speter * @param lep  Element in the ring to insert before
258251875Speter * @param nep  Element to insert
259251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
260251875Speter */
261251875Speter#define APR_RING_INSERT_BEFORE(lep, nep, link)				\
262251875Speter	APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)
263251875Speter
264251875Speter/**
265251875Speter * Insert the element nep into the ring after element lep
266251875Speter *   (..lep.. becomes ..lep..nep..)
267251875Speter * @warning This doesn't work for inserting after the last element or on
268251875Speter *   empty rings... see APR_RING_INSERT_TAIL for one that does
269251875Speter * @param lep  Element in the ring to insert after
270251875Speter * @param nep  Element to insert
271251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
272251875Speter */
273251875Speter#define APR_RING_INSERT_AFTER(lep, nep, link)				\
274251875Speter	APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)
275251875Speter
276251875Speter
277251875Speter/**
278251875Speter * Splice the sequence ep1..epN into the ring before the first element
279251875Speter *   (..hp.. becomes ..hp..ep1..epN..)
280251875Speter * @param hp   Head of the ring
281251875Speter * @param ep1  First element in the sequence to splice in
282251875Speter * @param epN  Last element in the sequence to splice in
283251875Speter * @param elem The name of the element struct
284251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
285251875Speter */
286251875Speter#define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link)			\
287251875Speter	APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link),	\
288251875Speter			     (ep1), (epN), link)
289251875Speter
290251875Speter/**
291251875Speter * Splice the sequence ep1..epN into the ring after the last element
292251875Speter *   (..hp.. becomes ..ep1..epN..hp..)
293251875Speter * @param hp   Head of the ring
294251875Speter * @param ep1  First element in the sequence to splice in
295251875Speter * @param epN  Last element in the sequence to splice in
296251875Speter * @param elem The name of the element struct
297251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
298251875Speter */
299251875Speter#define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link)			\
300251875Speter	APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link),	\
301251875Speter			     (ep1), (epN), link)
302251875Speter
303251875Speter/**
304251875Speter * Insert the element nep into the ring before the first element
305251875Speter *   (..hp.. becomes ..hp..nep..)
306251875Speter * @param hp   Head of the ring
307251875Speter * @param nep  Element to insert
308251875Speter * @param elem The name of the element struct
309251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
310251875Speter */
311251875Speter#define APR_RING_INSERT_HEAD(hp, nep, elem, link)			\
312251875Speter	APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)
313251875Speter
314251875Speter/**
315251875Speter * Insert the element nep into the ring after the last element
316251875Speter *   (..hp.. becomes ..nep..hp..)
317251875Speter * @param hp   Head of the ring
318251875Speter * @param nep  Element to insert
319251875Speter * @param elem The name of the element struct
320251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
321251875Speter */
322251875Speter#define APR_RING_INSERT_TAIL(hp, nep, elem, link)			\
323251875Speter	APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
324251875Speter
325251875Speter/**
326251875Speter * Concatenate ring h2 onto the end of ring h1, leaving h2 empty.
327251875Speter * @param h1   Head of the ring to concatenate onto
328251875Speter * @param h2   Head of the ring to concatenate
329251875Speter * @param elem The name of the element struct
330251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
331251875Speter */
332251875Speter#define APR_RING_CONCAT(h1, h2, elem, link) do {			\
333251875Speter	if (!APR_RING_EMPTY((h2), elem, link)) {			\
334251875Speter	    APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link),	\
335251875Speter				  APR_RING_FIRST((h2)),			\
336251875Speter				  APR_RING_LAST((h2)), link);		\
337251875Speter	    APR_RING_INIT((h2), elem, link);				\
338251875Speter	}								\
339251875Speter    } while (0)
340251875Speter
341251875Speter/**
342251875Speter * Prepend ring h2 onto the beginning of ring h1, leaving h2 empty.
343251875Speter * @param h1   Head of the ring to prepend onto
344251875Speter * @param h2   Head of the ring to prepend
345251875Speter * @param elem The name of the element struct
346251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
347251875Speter */
348251875Speter#define APR_RING_PREPEND(h1, h2, elem, link) do {			\
349251875Speter	if (!APR_RING_EMPTY((h2), elem, link)) {			\
350251875Speter	    APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((h1), elem, link),	\
351251875Speter				  APR_RING_FIRST((h2)),			\
352251875Speter				  APR_RING_LAST((h2)), link);		\
353251875Speter	    APR_RING_INIT((h2), elem, link);				\
354251875Speter	}								\
355251875Speter    } while (0)
356251875Speter
357251875Speter/**
358251875Speter * Unsplice a sequence of elements from a ring
359251875Speter * @warning The unspliced sequence is left with dangling pointers at either end
360251875Speter * @param ep1  First element in the sequence to unsplice
361251875Speter * @param epN  Last element in the sequence to unsplice
362251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
363251875Speter */
364251875Speter#define APR_RING_UNSPLICE(ep1, epN, link) do {				\
365251875Speter	APR_RING_NEXT(APR_RING_PREV((ep1), link), link) =		\
366251875Speter		     APR_RING_NEXT((epN), link);			\
367251875Speter	APR_RING_PREV(APR_RING_NEXT((epN), link), link) =		\
368251875Speter		     APR_RING_PREV((ep1), link);			\
369251875Speter    } while (0)
370251875Speter
371251875Speter/**
372251875Speter * Remove a single element from a ring
373251875Speter * @warning The unspliced element is left with dangling pointers at either end
374251875Speter * @param ep   Element to remove
375251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
376251875Speter */
377251875Speter#define APR_RING_REMOVE(ep, link)					\
378251875Speter    APR_RING_UNSPLICE((ep), (ep), link)
379251875Speter
380251875Speter/**
381251875Speter * Iterate over a ring
382251875Speter * @param ep The current element
383251875Speter * @param head The head of the ring
384251875Speter * @param elem The name of the element struct
385251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
386251875Speter */
387251875Speter#define APR_RING_FOREACH(ep, head, elem, link)                          \
388251875Speter    for (ep = APR_RING_FIRST(head);                                     \
389251875Speter         ep != APR_RING_SENTINEL(head, elem, link);                     \
390251875Speter         ep = APR_RING_NEXT(ep, link))
391251875Speter
392251875Speter/**
393251875Speter * Iterate over a ring safe against removal of the current element
394251875Speter * @param ep1 The current element
395251875Speter * @param ep2 Iteration cursor
396251875Speter * @param head The head of the ring
397251875Speter * @param elem The name of the element struct
398251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
399251875Speter */
400251875Speter#define APR_RING_FOREACH_SAFE(ep1, ep2, head, elem, link)               \
401251875Speter    for (ep1 = APR_RING_FIRST(head), ep2 = APR_RING_NEXT(ep1, link);    \
402251875Speter         ep1 != APR_RING_SENTINEL(head, elem, link);                    \
403251875Speter         ep1 = ep2, ep2 = APR_RING_NEXT(ep1, link))
404251875Speter
405251875Speter/* Debugging tools: */
406251875Speter
407251875Speter#ifdef APR_RING_DEBUG
408251875Speter#include <stdio.h>
409251875Speter#include <assert.h>
410251875Speter
411251875Speter#define APR_RING_CHECK_ONE(msg, ptr)					\
412251875Speter	fprintf(stderr, "*** %s %p\n", msg, ptr)
413251875Speter
414251875Speter#define APR_RING_CHECK(hp, elem, link, msg)				\
415251875Speter	APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)
416251875Speter
417251875Speter#define APR_RING_CHECK_ELEM(ep, elem, link, msg) do {			\
418251875Speter	struct elem *start = (ep);					\
419251875Speter	struct elem *here = start;					\
420251875Speter	fprintf(stderr, "*** ring check start -- %s\n", msg);		\
421251875Speter	do {								\
422251875Speter	    fprintf(stderr, "\telem %p\n", here);			\
423251875Speter	    fprintf(stderr, "\telem->next %p\n",			\
424251875Speter		    APR_RING_NEXT(here, link));				\
425251875Speter	    fprintf(stderr, "\telem->prev %p\n",			\
426251875Speter		    APR_RING_PREV(here, link));				\
427251875Speter	    fprintf(stderr, "\telem->next->prev %p\n",			\
428251875Speter		    APR_RING_PREV(APR_RING_NEXT(here, link), link));	\
429251875Speter	    fprintf(stderr, "\telem->prev->next %p\n",			\
430251875Speter		    APR_RING_NEXT(APR_RING_PREV(here, link), link));	\
431251875Speter	    if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
432251875Speter		fprintf(stderr, "\t*** elem->next->prev != elem\n");	\
433251875Speter		break;							\
434251875Speter	    }								\
435251875Speter	    if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
436251875Speter		fprintf(stderr, "\t*** elem->prev->next != elem\n");	\
437251875Speter		break;							\
438251875Speter	    }								\
439251875Speter	    here = APR_RING_NEXT(here, link);				\
440251875Speter	} while (here != start);					\
441251875Speter	fprintf(stderr, "*** ring check end\n");			\
442251875Speter    } while (0)
443251875Speter
444251875Speter#define APR_RING_CHECK_CONSISTENCY(hp, elem, link)			\
445251875Speter	APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
446251875Speter					elem, link)
447251875Speter
448251875Speter#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do {		\
449251875Speter	struct elem *start = (ep);					\
450251875Speter	struct elem *here = start;					\
451251875Speter	do {								\
452251875Speter	    assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
453251875Speter	    assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
454251875Speter	    here = APR_RING_NEXT(here, link);				\
455251875Speter	} while (here != start);					\
456251875Speter    } while (0)
457251875Speter
458251875Speter#else
459251875Speter/**
460251875Speter * Print a single pointer value to STDERR
461251875Speter *   (This is a no-op unless APR_RING_DEBUG is defined.)
462251875Speter * @param msg Descriptive message
463251875Speter * @param ptr Pointer value to print
464251875Speter */
465251875Speter#define APR_RING_CHECK_ONE(msg, ptr)
466251875Speter/**
467251875Speter * Dump all ring pointers to STDERR, starting with the head and looping all
468251875Speter * the way around the ring back to the head.  Aborts if an inconsistency
469251875Speter * is found.
470251875Speter *   (This is a no-op unless APR_RING_DEBUG is defined.)
471251875Speter * @param hp   Head of the ring
472251875Speter * @param elem The name of the element struct
473251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
474251875Speter * @param msg  Descriptive message
475251875Speter */
476251875Speter#define APR_RING_CHECK(hp, elem, link, msg)
477251875Speter/**
478251875Speter * Loops around a ring and checks all the pointers for consistency.  Pops
479251875Speter * an assertion if any inconsistency is found.  Same idea as APR_RING_CHECK()
480251875Speter * except that it's silent if all is well.
481251875Speter *   (This is a no-op unless APR_RING_DEBUG is defined.)
482251875Speter * @param hp   Head of the ring
483251875Speter * @param elem The name of the element struct
484251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
485251875Speter */
486251875Speter#define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
487251875Speter/**
488251875Speter * Dump all ring pointers to STDERR, starting with the given element and
489251875Speter * looping all the way around the ring back to that element.  Aborts if
490251875Speter * an inconsistency is found.
491251875Speter *   (This is a no-op unless APR_RING_DEBUG is defined.)
492251875Speter * @param ep   The element
493251875Speter * @param elem The name of the element struct
494251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
495251875Speter * @param msg  Descriptive message
496251875Speter */
497251875Speter#define APR_RING_CHECK_ELEM(ep, elem, link, msg)
498251875Speter/**
499251875Speter * Loops around a ring, starting with the given element, and checks all
500251875Speter * the pointers for consistency.  Pops an assertion if any inconsistency
501251875Speter * is found.  Same idea as APR_RING_CHECK_ELEM() except that it's silent
502251875Speter * if all is well.
503251875Speter *   (This is a no-op unless APR_RING_DEBUG is defined.)
504251875Speter * @param ep   The element
505251875Speter * @param elem The name of the element struct
506251875Speter * @param link The name of the APR_RING_ENTRY in the element struct
507251875Speter */
508251875Speter#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
509251875Speter#endif
510251875Speter
511251875Speter/** @} */
512251875Speter
513251875Speter#endif /* !APR_RING_H */
514