00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #ifndef APR_RING_H
00066 #define APR_RING_H
00067
00073
00074
00075
00076 #include "apr_general.h"
00077
00108 #define APR_RING_ENTRY(elem) \
00109 struct { \
00110 struct elem *next; \
00111 struct elem *prev; \
00112 }
00113
00129 #define APR_RING_HEAD(head, elem) \
00130 struct head { \
00131 struct elem *next; \
00132 struct elem *prev; \
00133 }
00134
00197 #define APR_RING_SENTINEL(hp, elem, link) \
00198 (struct elem *)((char *)(hp) - APR_OFFSETOF(struct elem, link))
00199
00204 #define APR_RING_FIRST(hp) (hp)->next
00205
00209 #define APR_RING_LAST(hp) (hp)->prev
00210
00215 #define APR_RING_NEXT(ep, link) (ep)->link.next
00216
00221 #define APR_RING_PREV(ep, link) (ep)->link.prev
00222
00223
00230 #define APR_RING_INIT(hp, elem, link) do { \
00231 APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
00232 APR_RING_LAST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
00233 } while (0)
00234
00242 #define APR_RING_EMPTY(hp, elem, link) \
00243 (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))
00244
00250 #define APR_RING_ELEM_INIT(ep, link) do { \
00251 APR_RING_NEXT((ep), link) = (ep); \
00252 APR_RING_PREV((ep), link) = (ep); \
00253 } while (0)
00254
00255
00266 #define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do { \
00267 APR_RING_NEXT((epN), link) = (lep); \
00268 APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link); \
00269 APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1); \
00270 APR_RING_PREV((lep), link) = (epN); \
00271 } while (0)
00272
00283 #define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do { \
00284 APR_RING_PREV((ep1), link) = (lep); \
00285 APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link); \
00286 APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN); \
00287 APR_RING_NEXT((lep), link) = (ep1); \
00288 } while (0)
00289
00299 #define APR_RING_INSERT_BEFORE(lep, nep, link) \
00300 APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)
00301
00311 #define APR_RING_INSERT_AFTER(lep, nep, link) \
00312 APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)
00313
00314
00324 #define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) \
00325 APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link), \
00326 (ep1), (epN), link)
00327
00337 #define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \
00338 APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link), \
00339 (ep1), (epN), link)
00340
00349 #define APR_RING_INSERT_HEAD(hp, nep, elem, link) \
00350 APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)
00351
00360 #define APR_RING_INSERT_TAIL(hp, nep, elem, link) \
00361 APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
00362
00370 #define APR_RING_CONCAT(h1, h2, elem, link) do { \
00371 if (!APR_RING_EMPTY((h2), elem, link)) { \
00372 APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link), \
00373 APR_RING_FIRST((h2)), \
00374 APR_RING_LAST((h2)), link); \
00375 APR_RING_INIT((h2), elem, link); \
00376 } \
00377 } while (0)
00378
00386 #define APR_RING_PREPEND(h1, h2, elem, link) do { \
00387 if (!APR_RING_EMPTY((h2), elem, link)) { \
00388 APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((h1), elem, link), \
00389 APR_RING_FIRST((h2)), \
00390 APR_RING_LAST((h2)), link); \
00391 APR_RING_INIT((h2), elem, link); \
00392 } \
00393 } while (0)
00394
00402 #define APR_RING_UNSPLICE(ep1, epN, link) do { \
00403 APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \
00404 APR_RING_NEXT((epN), link); \
00405 APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \
00406 APR_RING_PREV((ep1), link); \
00407 } while (0)
00408
00415 #define APR_RING_REMOVE(ep, link) \
00416 APR_RING_UNSPLICE((ep), (ep), link)
00417
00418
00462 #define APR_RING_FOREACH(ep, hp, elem, link) \
00463 for ((ep) = APR_RING_FIRST((hp)); \
00464 (ep) != APR_RING_SENTINEL((hp), elem, link); \
00465 (ep) = APR_RING_NEXT((ep), link))
00466
00475 #define APR_RING_FOREACH_REVERSE(ep, hp, elem, link) \
00476 for ((ep) = APR_RING_LAST((hp)); \
00477 (ep) != APR_RING_SENTINEL((hp), elem, link); \
00478 (ep) = APR_RING_PREV((ep), link))
00479
00480
00481
00482
00483 #ifdef APR_RING_DEBUG
00484 #include <stdio.h>
00485 #include <assert.h>
00486
00487 #define APR_RING_CHECK_ONE(msg, ptr) \
00488 fprintf(stderr, "*** %s %p\n", msg, ptr)
00489
00490 #define APR_RING_CHECK(hp, elem, link, msg) \
00491 APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)
00492
00493 #define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \
00494 struct elem *start = (ep); \
00495 struct elem *here = start; \
00496 fprintf(stderr, "*** ring check start -- %s\n", msg); \
00497 do { \
00498 fprintf(stderr, "\telem %p\n", here); \
00499 fprintf(stderr, "\telem->next %p\n", \
00500 APR_RING_NEXT(here, link)); \
00501 fprintf(stderr, "\telem->prev %p\n", \
00502 APR_RING_PREV(here, link)); \
00503 fprintf(stderr, "\telem->next->prev %p\n", \
00504 APR_RING_PREV(APR_RING_NEXT(here, link), link)); \
00505 fprintf(stderr, "\telem->prev->next %p\n", \
00506 APR_RING_NEXT(APR_RING_PREV(here, link), link)); \
00507 if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
00508 fprintf(stderr, "\t*** elem->next->prev != elem\n"); \
00509 break; \
00510 } \
00511 if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
00512 fprintf(stderr, "\t*** elem->prev->next != elem\n"); \
00513 break; \
00514 } \
00515 here = APR_RING_NEXT(here, link); \
00516 } while (here != start); \
00517 fprintf(stderr, "*** ring check end\n"); \
00518 } while (0)
00519
00520 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link) \
00521 APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
00522 elem, link)
00523
00524 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do { \
00525 struct elem *start = (ep); \
00526 struct elem *here = start; \
00527 do { \
00528 assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
00529 assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
00530 here = APR_RING_NEXT(here, link); \
00531 } while (here != start); \
00532 } while (0)
00533
00534 #else
00535
00541 #define APR_RING_CHECK_ONE(msg, ptr)
00542
00552 #define APR_RING_CHECK(hp, elem, link, msg)
00553
00562 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
00563
00573 #define APR_RING_CHECK_ELEM(ep, elem, link, msg)
00574
00584 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
00585 #endif
00586
00589 #endif