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.