Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

apr_ring.h

Go to the documentation of this file.
00001 /* Copyright 2000-2004 The Apache Software Foundation 00002 * 00003 * Licensed under the Apache License, Version 2.0 (the "License"); 00004 * you may not use this file except in compliance with the License. 00005 * You may obtain a copy of the License at 00006 * 00007 * http://www.apache.org/licenses/LICENSE-2.0 00008 * 00009 * Unless required by applicable law or agreed to in writing, software 00010 * distributed under the License is distributed on an "AS IS" BASIS, 00011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 * See the License for the specific language governing permissions and 00013 * limitations under the License. 00014 */ 00015 00016 /* 00017 * This code draws heavily from the 4.4BSD <sys/queue.h> macros 00018 * and Dean Gaudet's "splim/ring.h". 00019 * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h> 00020 * <http://www.arctic.org/~dean/splim/> 00021 * 00022 * We'd use Dean's code directly if we could guarantee the 00023 * availability of inline functions. 00024 */ 00025 00026 #ifndef APR_RING_H 00027 #define APR_RING_H 00028 00034 /* 00035 * for offsetof() 00036 */ 00037 #include "apr_general.h" 00038 00069 #define APR_RING_ENTRY(elem) \ 00070 struct { \ 00071 struct elem *next; \ 00072 struct elem *prev; \ 00073 } 00074 00090 #define APR_RING_HEAD(head, elem) \ 00091 struct head { \ 00092 struct elem *next; \ 00093 struct elem *prev; \ 00094 } 00095 00158 #define APR_RING_SENTINEL(hp, elem, link) \ 00159 (struct elem *)((char *)(hp) - APR_OFFSETOF(struct elem, link)) 00160 00165 #define APR_RING_FIRST(hp) (hp)->next 00166 00170 #define APR_RING_LAST(hp) (hp)->prev 00171 00176 #define APR_RING_NEXT(ep, link) (ep)->link.next 00177 00182 #define APR_RING_PREV(ep, link) (ep)->link.prev 00183 00184 00191 #define APR_RING_INIT(hp, elem, link) do { \ 00192 APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link); \ 00193 APR_RING_LAST((hp)) = APR_RING_SENTINEL((hp), elem, link); \ 00194 } while (0) 00195 00203 #define APR_RING_EMPTY(hp, elem, link) \ 00204 (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link)) 00205 00211 #define APR_RING_ELEM_INIT(ep, link) do { \ 00212 APR_RING_NEXT((ep), link) = (ep); \ 00213 APR_RING_PREV((ep), link) = (ep); \ 00214 } while (0) 00215 00216 00227 #define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do { \ 00228 APR_RING_NEXT((epN), link) = (lep); \ 00229 APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link); \ 00230 APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1); \ 00231 APR_RING_PREV((lep), link) = (epN); \ 00232 } while (0) 00233 00244 #define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do { \ 00245 APR_RING_PREV((ep1), link) = (lep); \ 00246 APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link); \ 00247 APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN); \ 00248 APR_RING_NEXT((lep), link) = (ep1); \ 00249 } while (0) 00250 00260 #define APR_RING_INSERT_BEFORE(lep, nep, link) \ 00261 APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link) 00262 00272 #define APR_RING_INSERT_AFTER(lep, nep, link) \ 00273 APR_RING_SPLICE_AFTER((lep), (nep), (nep), link) 00274 00275 00285 #define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) \ 00286 APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link), \ 00287 (ep1), (epN), link) 00288 00298 #define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \ 00299 APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link), \ 00300 (ep1), (epN), link) 00301 00310 #define APR_RING_INSERT_HEAD(hp, nep, elem, link) \ 00311 APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link) 00312 00321 #define APR_RING_INSERT_TAIL(hp, nep, elem, link) \ 00322 APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link) 00323 00331 #define APR_RING_CONCAT(h1, h2, elem, link) do { \ 00332 if (!APR_RING_EMPTY((h2), elem, link)) { \ 00333 APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link), \ 00334 APR_RING_FIRST((h2)), \ 00335 APR_RING_LAST((h2)), link); \ 00336 APR_RING_INIT((h2), elem, link); \ 00337 } \ 00338 } while (0) 00339 00347 #define APR_RING_PREPEND(h1, h2, elem, link) do { \ 00348 if (!APR_RING_EMPTY((h2), elem, link)) { \ 00349 APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((h1), elem, link), \ 00350 APR_RING_FIRST((h2)), \ 00351 APR_RING_LAST((h2)), link); \ 00352 APR_RING_INIT((h2), elem, link); \ 00353 } \ 00354 } while (0) 00355 00363 #define APR_RING_UNSPLICE(ep1, epN, link) do { \ 00364 APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \ 00365 APR_RING_NEXT((epN), link); \ 00366 APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \ 00367 APR_RING_PREV((ep1), link); \ 00368 } while (0) 00369 00376 #define APR_RING_REMOVE(ep, link) \ 00377 APR_RING_UNSPLICE((ep), (ep), link) 00378 00379 00423 #define APR_RING_FOREACH(ep, hp, elem, link) \ 00424 for ((ep) = APR_RING_FIRST((hp)); \ 00425 (ep) != APR_RING_SENTINEL((hp), elem, link); \ 00426 (ep) = APR_RING_NEXT((ep), link)) 00427 00436 #define APR_RING_FOREACH_REVERSE(ep, hp, elem, link) \ 00437 for ((ep) = APR_RING_LAST((hp)); \ 00438 (ep) != APR_RING_SENTINEL((hp), elem, link); \ 00439 (ep) = APR_RING_PREV((ep), link)) 00440 00441 00442 /* Debugging tools: */ 00443 00444 #ifdef APR_RING_DEBUG 00445 #include <stdio.h> 00446 #include <assert.h> 00447 00448 #define APR_RING_CHECK_ONE(msg, ptr) \ 00449 fprintf(stderr, "*** %s %p\n", msg, ptr) 00450 00451 #define APR_RING_CHECK(hp, elem, link, msg) \ 00452 APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg) 00453 00454 #define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \ 00455 struct elem *start = (ep); \ 00456 struct elem *here = start; \ 00457 fprintf(stderr, "*** ring check start -- %s\n", msg); \ 00458 do { \ 00459 fprintf(stderr, "\telem %p\n", here); \ 00460 fprintf(stderr, "\telem->next %p\n", \ 00461 APR_RING_NEXT(here, link)); \ 00462 fprintf(stderr, "\telem->prev %p\n", \ 00463 APR_RING_PREV(here, link)); \ 00464 fprintf(stderr, "\telem->next->prev %p\n", \ 00465 APR_RING_PREV(APR_RING_NEXT(here, link), link)); \ 00466 fprintf(stderr, "\telem->prev->next %p\n", \ 00467 APR_RING_NEXT(APR_RING_PREV(here, link), link)); \ 00468 if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \ 00469 fprintf(stderr, "\t*** elem->next->prev != elem\n"); \ 00470 break; \ 00471 } \ 00472 if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \ 00473 fprintf(stderr, "\t*** elem->prev->next != elem\n"); \ 00474 break; \ 00475 } \ 00476 here = APR_RING_NEXT(here, link); \ 00477 } while (here != start); \ 00478 fprintf(stderr, "*** ring check end\n"); \ 00479 } while (0) 00480 00481 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link) \ 00482 APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\ 00483 elem, link) 00484 00485 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do { \ 00486 struct elem *start = (ep); \ 00487 struct elem *here = start; \ 00488 do { \ 00489 assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \ 00490 assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \ 00491 here = APR_RING_NEXT(here, link); \ 00492 } while (here != start); \ 00493 } while (0) 00494 00495 #else 00496 00502 #define APR_RING_CHECK_ONE(msg, ptr) 00503 00513 #define APR_RING_CHECK(hp, elem, link, msg) 00514 00523 #define APR_RING_CHECK_CONSISTENCY(hp, elem, link) 00524 00534 #define APR_RING_CHECK_ELEM(ep, elem, link, msg) 00535 00545 #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) 00546 #endif 00547 00550 #endif /* !APR_RING_H */

Generated on Tue Aug 10 17:42:34 2004 for Apache Portable Runtime by doxygen 1.3.7