70 #define APR_RING_ENTRY(elem) \
72 struct elem * volatile next; \
73 struct elem * volatile prev; \
91 #define APR_RING_HEAD(head, elem) \
93 struct elem * volatile next; \
94 struct elem * volatile prev; \
159 #define APR_RING_SENTINEL(hp, elem, link) \
160 (struct elem *)((char *)(&(hp)->next) - APR_OFFSETOF(struct elem, link))
166 #define APR_RING_FIRST(hp) (hp)->next
171 #define APR_RING_LAST(hp) (hp)->prev
177 #define APR_RING_NEXT(ep, link) (ep)->link.next
183 #define APR_RING_PREV(ep, link) (ep)->link.prev
192 #define APR_RING_INIT(hp, elem, link) do { \
193 APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
194 APR_RING_LAST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
204 #define APR_RING_EMPTY(hp, elem, link) \
205 (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))
212 #define APR_RING_ELEM_INIT(ep, link) do { \
213 APR_RING_NEXT((ep), link) = (ep); \
214 APR_RING_PREV((ep), link) = (ep); \
228 #define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do { \
229 APR_RING_NEXT((epN), link) = (lep); \
230 APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link); \
231 APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1); \
232 APR_RING_PREV((lep), link) = (epN); \
245 #define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do { \
246 APR_RING_PREV((ep1), link) = (lep); \
247 APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link); \
248 APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN); \
249 APR_RING_NEXT((lep), link) = (ep1); \
261 #define APR_RING_INSERT_BEFORE(lep, nep, link) \
262 APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)
273 #define APR_RING_INSERT_AFTER(lep, nep, link) \
274 APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)
286 #define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) do { \
287 APR_RING_PREV((ep1), link) = APR_RING_SENTINEL((hp), elem, link);\
288 APR_RING_NEXT((epN), link) = APR_RING_FIRST((hp)); \
289 APR_RING_PREV(APR_RING_FIRST((hp)), link) = (epN); \
290 APR_RING_FIRST((hp)) = (ep1); \
302 #define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) do { \
303 APR_RING_NEXT((epN), link) = APR_RING_SENTINEL((hp), elem, link);\
304 APR_RING_PREV((ep1), link) = APR_RING_LAST((hp)); \
305 APR_RING_NEXT(APR_RING_LAST((hp)), link) = (ep1); \
306 APR_RING_LAST((hp)) = (epN); \
317 #define APR_RING_INSERT_HEAD(hp, nep, elem, link) \
318 APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)
328 #define APR_RING_INSERT_TAIL(hp, nep, elem, link) \
329 APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
338 #define APR_RING_CONCAT(h1, h2, elem, link) do { \
339 if (!APR_RING_EMPTY((h2), elem, link)) { \
340 APR_RING_SPLICE_TAIL((h1), APR_RING_FIRST((h2)), \
341 APR_RING_LAST((h2)), elem, link); \
342 APR_RING_INIT((h2), elem, link); \
353 #define APR_RING_PREPEND(h1, h2, elem, link) do { \
354 if (!APR_RING_EMPTY((h2), elem, link)) { \
355 APR_RING_SPLICE_HEAD((h1), APR_RING_FIRST((h2)), \
356 APR_RING_LAST((h2)), elem, link); \
357 APR_RING_INIT((h2), elem, link); \
368 #define APR_RING_UNSPLICE(ep1, epN, link) do { \
369 APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \
370 APR_RING_NEXT((epN), link); \
371 APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \
372 APR_RING_PREV((ep1), link); \
381 #define APR_RING_REMOVE(ep, link) \
382 APR_RING_UNSPLICE((ep), (ep), link)
391 #define APR_RING_FOREACH(ep, head, elem, link) \
392 for (ep = APR_RING_FIRST(head); \
393 ep != APR_RING_SENTINEL(head, elem, link); \
394 ep = APR_RING_NEXT(ep, link))
404 #define APR_RING_FOREACH_SAFE(ep1, ep2, head, elem, link) \
405 for (ep1 = APR_RING_FIRST(head), ep2 = APR_RING_NEXT(ep1, link); \
406 ep1 != APR_RING_SENTINEL(head, elem, link); \
407 ep1 = ep2, ep2 = APR_RING_NEXT(ep1, link))
411 #ifdef APR_RING_DEBUG
415 #define APR_RING_CHECK_ONE(msg, ptr) \
416 fprintf(stderr, "*** %s %p\n", msg, ptr)
418 #define APR_RING_CHECK(hp, elem, link, msg) \
419 APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)
421 #define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \
422 struct elem *start = (ep); \
423 struct elem *here = start; \
424 fprintf(stderr, "*** ring check start -- %s\n", msg); \
426 fprintf(stderr, "\telem %p\n", here); \
427 fprintf(stderr, "\telem->next %p\n", \
428 APR_RING_NEXT(here, link)); \
429 fprintf(stderr, "\telem->prev %p\n", \
430 APR_RING_PREV(here, link)); \
431 fprintf(stderr, "\telem->next->prev %p\n", \
432 APR_RING_PREV(APR_RING_NEXT(here, link), link)); \
433 fprintf(stderr, "\telem->prev->next %p\n", \
434 APR_RING_NEXT(APR_RING_PREV(here, link), link)); \
435 if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
436 fprintf(stderr, "\t*** elem->next->prev != elem\n"); \
439 if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
440 fprintf(stderr, "\t*** elem->prev->next != elem\n"); \
443 here = APR_RING_NEXT(here, link); \
444 } while (here != start); \
445 fprintf(stderr, "*** ring check end\n"); \
448 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link) \
449 APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
452 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do { \
453 struct elem *start = (ep); \
454 struct elem *here = start; \
456 assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
457 assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
458 here = APR_RING_NEXT(here, link); \
459 } while (here != start); \
469 #define APR_RING_CHECK_ONE(msg, ptr)
480 #define APR_RING_CHECK(hp, elem, link, msg)
490 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
501 #define APR_RING_CHECK_ELEM(ep, elem, link, msg)
512 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
APR Miscellaneous library routines.