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) \
287 APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link), \
299 #define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \
300 APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link), \
311 #define APR_RING_INSERT_HEAD(hp, nep, elem, link) \
312 APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)
322 #define APR_RING_INSERT_TAIL(hp, nep, elem, link) \
323 APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
332 #define APR_RING_CONCAT(h1, h2, elem, link) do { \
333 if (!APR_RING_EMPTY((h2), elem, link)) { \
334 APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link), \
335 APR_RING_FIRST((h2)), \
336 APR_RING_LAST((h2)), link); \
337 APR_RING_INIT((h2), elem, link); \
348 #define APR_RING_PREPEND(h1, h2, elem, link) do { \
349 if (!APR_RING_EMPTY((h2), elem, link)) { \
350 APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((h1), elem, link), \
351 APR_RING_FIRST((h2)), \
352 APR_RING_LAST((h2)), link); \
353 APR_RING_INIT((h2), elem, link); \
364 #define APR_RING_UNSPLICE(ep1, epN, link) do { \
365 APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \
366 APR_RING_NEXT((epN), link); \
367 APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \
368 APR_RING_PREV((ep1), link); \
377 #define APR_RING_REMOVE(ep, link) \
378 APR_RING_UNSPLICE((ep), (ep), link)
387 #define APR_RING_FOREACH(ep, head, elem, link) \
388 for (ep = APR_RING_FIRST(head); \
389 ep != APR_RING_SENTINEL(head, elem, link); \
390 ep = APR_RING_NEXT(ep, link))
400 #define APR_RING_FOREACH_SAFE(ep1, ep2, head, elem, link) \
401 for (ep1 = APR_RING_FIRST(head), ep2 = APR_RING_NEXT(ep1, link); \
402 ep1 != APR_RING_SENTINEL(head, elem, link); \
403 ep1 = ep2, ep2 = APR_RING_NEXT(ep1, link))
407 #ifdef APR_RING_DEBUG
411 #define APR_RING_CHECK_ONE(msg, ptr) \
412 fprintf(stderr, "*** %s %p\n", msg, ptr)
414 #define APR_RING_CHECK(hp, elem, link, msg) \
415 APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)
417 #define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \
418 struct elem *start = (ep); \
419 struct elem *here = start; \
420 fprintf(stderr, "*** ring check start -- %s\n", msg); \
422 fprintf(stderr, "\telem %p\n", here); \
423 fprintf(stderr, "\telem->next %p\n", \
424 APR_RING_NEXT(here, link)); \
425 fprintf(stderr, "\telem->prev %p\n", \
426 APR_RING_PREV(here, link)); \
427 fprintf(stderr, "\telem->next->prev %p\n", \
428 APR_RING_PREV(APR_RING_NEXT(here, link), link)); \
429 fprintf(stderr, "\telem->prev->next %p\n", \
430 APR_RING_NEXT(APR_RING_PREV(here, link), link)); \
431 if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
432 fprintf(stderr, "\t*** elem->next->prev != elem\n"); \
435 if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
436 fprintf(stderr, "\t*** elem->prev->next != elem\n"); \
439 here = APR_RING_NEXT(here, link); \
440 } while (here != start); \
441 fprintf(stderr, "*** ring check end\n"); \
444 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link) \
445 APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
448 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do { \
449 struct elem *start = (ep); \
450 struct elem *here = start; \
452 assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
453 assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
454 here = APR_RING_NEXT(here, link); \
455 } while (here != start); \
465 #define APR_RING_CHECK_ONE(msg, ptr)
476 #define APR_RING_CHECK(hp, elem, link, msg)
486 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
497 #define APR_RING_CHECK_ELEM(ep, elem, link, msg)
508 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
APR Miscellaneous library routines.