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 #ifndef APR_RING_H
00028 #define APR_RING_H
00029
00035
00036
00037
00038 #include "apr_general.h"
00039
00070 #define APR_RING_ENTRY(elem) \
00071 struct { \
00072 struct elem *next; \
00073 struct elem *prev; \
00074 }
00075
00091 #define APR_RING_HEAD(head, elem) \
00092 struct head { \
00093 struct elem *next; \
00094 struct elem *prev; \
00095 }
00096
00159 #define APR_RING_SENTINEL(hp, elem, link) \
00160 (struct elem *)((char *)(hp) - APR_OFFSETOF(struct elem, link))
00161
00166 #define APR_RING_FIRST(hp) (hp)->next
00167
00171 #define APR_RING_LAST(hp) (hp)->prev
00172
00177 #define APR_RING_NEXT(ep, link) (ep)->link.next
00178
00183 #define APR_RING_PREV(ep, link) (ep)->link.prev
00184
00185
00192 #define APR_RING_INIT(hp, elem, link) do { \
00193 APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
00194 APR_RING_LAST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
00195 } while (0)
00196
00204 #define APR_RING_EMPTY(hp, elem, link) \
00205 (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))
00206
00212 #define APR_RING_ELEM_INIT(ep, link) do { \
00213 APR_RING_NEXT((ep), link) = (ep); \
00214 APR_RING_PREV((ep), link) = (ep); \
00215 } while (0)
00216
00217
00228 #define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do { \
00229 APR_RING_NEXT((epN), link) = (lep); \
00230 APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link); \
00231 APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1); \
00232 APR_RING_PREV((lep), link) = (epN); \
00233 } while (0)
00234
00245 #define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do { \
00246 APR_RING_PREV((ep1), link) = (lep); \
00247 APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link); \
00248 APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN); \
00249 APR_RING_NEXT((lep), link) = (ep1); \
00250 } while (0)
00251
00261 #define APR_RING_INSERT_BEFORE(lep, nep, link) \
00262 APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)
00263
00273 #define APR_RING_INSERT_AFTER(lep, nep, link) \
00274 APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)
00275
00276
00286 #define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) \
00287 APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link), \
00288 (ep1), (epN), link)
00289
00299 #define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \
00300 APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link), \
00301 (ep1), (epN), link)
00302
00311 #define APR_RING_INSERT_HEAD(hp, nep, elem, link) \
00312 APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)
00313
00322 #define APR_RING_INSERT_TAIL(hp, nep, elem, link) \
00323 APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
00324
00332 #define APR_RING_CONCAT(h1, h2, elem, link) do { \
00333 if (!APR_RING_EMPTY((h2), elem, link)) { \
00334 APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link), \
00335 APR_RING_FIRST((h2)), \
00336 APR_RING_LAST((h2)), link); \
00337 APR_RING_INIT((h2), elem, link); \
00338 } \
00339 } while (0)
00340
00348 #define APR_RING_PREPEND(h1, h2, elem, link) do { \
00349 if (!APR_RING_EMPTY((h2), elem, link)) { \
00350 APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((h1), elem, link), \
00351 APR_RING_FIRST((h2)), \
00352 APR_RING_LAST((h2)), link); \
00353 APR_RING_INIT((h2), elem, link); \
00354 } \
00355 } while (0)
00356
00364 #define APR_RING_UNSPLICE(ep1, epN, link) do { \
00365 APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \
00366 APR_RING_NEXT((epN), link); \
00367 APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \
00368 APR_RING_PREV((ep1), link); \
00369 } while (0)
00370
00377 #define APR_RING_REMOVE(ep, link) \
00378 APR_RING_UNSPLICE((ep), (ep), link)
00379
00380
00381
00382
00383 #ifdef APR_RING_DEBUG
00384 #include <stdio.h>
00385 #include <assert.h>
00386
00387 #define APR_RING_CHECK_ONE(msg, ptr) \
00388 fprintf(stderr, "*** %s %p\n", msg, ptr)
00389
00390 #define APR_RING_CHECK(hp, elem, link, msg) \
00391 APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)
00392
00393 #define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \
00394 struct elem *start = (ep); \
00395 struct elem *here = start; \
00396 fprintf(stderr, "*** ring check start -- %s\n", msg); \
00397 do { \
00398 fprintf(stderr, "\telem %p\n", here); \
00399 fprintf(stderr, "\telem->next %p\n", \
00400 APR_RING_NEXT(here, link)); \
00401 fprintf(stderr, "\telem->prev %p\n", \
00402 APR_RING_PREV(here, link)); \
00403 fprintf(stderr, "\telem->next->prev %p\n", \
00404 APR_RING_PREV(APR_RING_NEXT(here, link), link)); \
00405 fprintf(stderr, "\telem->prev->next %p\n", \
00406 APR_RING_NEXT(APR_RING_PREV(here, link), link)); \
00407 if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
00408 fprintf(stderr, "\t*** elem->next->prev != elem\n"); \
00409 break; \
00410 } \
00411 if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
00412 fprintf(stderr, "\t*** elem->prev->next != elem\n"); \
00413 break; \
00414 } \
00415 here = APR_RING_NEXT(here, link); \
00416 } while (here != start); \
00417 fprintf(stderr, "*** ring check end\n"); \
00418 } while (0)
00419
00420 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link) \
00421 APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
00422 elem, link)
00423
00424 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do { \
00425 struct elem *start = (ep); \
00426 struct elem *here = start; \
00427 do { \
00428 assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
00429 assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
00430 here = APR_RING_NEXT(here, link); \
00431 } while (here != start); \
00432 } while (0)
00433
00434 #else
00435
00441 #define APR_RING_CHECK_ONE(msg, ptr)
00442
00452 #define APR_RING_CHECK(hp, elem, link, msg)
00453
00462 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
00463
00473 #define APR_RING_CHECK_ELEM(ep, elem, link, msg)
00474
00484 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
00485 #endif
00486
00489 #endif