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

apr_ring.h

Go to the documentation of this file.
00001 /* ==================================================================== 00002 * The Apache Software License, Version 1.1 00003 * 00004 * Copyright (c) 2000-2003 The Apache Software Foundation. All rights 00005 * reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * 1. Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 00014 * 2. Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in 00016 * the documentation and/or other materials provided with the 00017 * distribution. 00018 * 00019 * 3. The end-user documentation included with the redistribution, 00020 * if any, must include the following acknowledgment: 00021 * "This product includes software developed by the 00022 * Apache Software Foundation (http://www.apache.org/)." 00023 * Alternately, this acknowledgment may appear in the software itself, 00024 * if and wherever such third-party acknowledgments normally appear. 00025 * 00026 * 4. The names "Apache" and "Apache Software Foundation" must 00027 * not be used to endorse or promote products derived from this 00028 * software without prior written permission. For written 00029 * permission, please contact apache@apache.org. 00030 * 00031 * 5. Products derived from this software may not be called "Apache", 00032 * nor may "Apache" appear in their name, without prior written 00033 * permission of the Apache Software Foundation. 00034 * 00035 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 00036 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00037 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00038 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 00039 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00040 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00041 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 00042 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00043 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00044 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00045 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00046 * SUCH DAMAGE. 00047 * ==================================================================== 00048 * 00049 * This software consists of voluntary contributions made by many 00050 * individuals on behalf of the Apache Software Foundation. For more 00051 * information on the Apache Software Foundation, please see 00052 * <http://www.apache.org/>. 00053 */ 00054 00055 /* 00056 * This code draws heavily from the 4.4BSD <sys/queue.h> macros 00057 * and Dean Gaudet's "splim/ring.h". 00058 * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h> 00059 * <http://www.arctic.org/~dean/splim/> 00060 * 00061 * We'd use Dean's code directly if we could guarantee the 00062 * availability of inline functions. 00063 */ 00064 00065 #ifndef APR_RING_H 00066 #define APR_RING_H 00067 00073 /* 00074 * for offsetof() 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 /* Debugging tools: */ 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 /* !APR_RING_H */

Generated on Wed Sep 1 05:15:08 2004 for Apache Portable Runtime by doxygen 1.3.8