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 Fri Dec 26 01:40:48 2003 for Apache Portable Runtime by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002