home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 November / CMCD1104.ISO / Software / Complet / Apache / apache_2.0.52-win32-x86-no_ssl.msi / Data.Cab / F277226_apr_ring.h < prev    next >
C/C++ Source or Header  |  2004-02-13  |  21KB  |  551 lines

  1. /* Copyright 2000-2004 The Apache Software Foundation
  2.  *
  3.  * Licensed under the Apache License, Version 2.0 (the "License");
  4.  * you may not use this file except in compliance with the License.
  5.  * You may obtain a copy of the License at
  6.  *
  7.  *     http://www.apache.org/licenses/LICENSE-2.0
  8.  *
  9.  * Unless required by applicable law or agreed to in writing, software
  10.  * distributed under the License is distributed on an "AS IS" BASIS,
  11.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12.  * See the License for the specific language governing permissions and
  13.  * limitations under the License.
  14.  */
  15.  
  16. /*
  17.  * This code draws heavily from the 4.4BSD <sys/queue.h> macros
  18.  * and Dean Gaudet's "splim/ring.h".
  19.  * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h>
  20.  * <http://www.arctic.org/~dean/splim/>
  21.  *
  22.  * We'd use Dean's code directly if we could guarantee the
  23.  * availability of inline functions.
  24.  */
  25.  
  26. #ifndef APR_RING_H
  27. #define APR_RING_H
  28.  
  29. /**
  30.  * @file apr_ring.h
  31.  * @brief APR Rings
  32.  */
  33.  
  34. /*
  35.  * for offsetof()
  36.  */
  37. #include "apr_general.h"
  38.  
  39. /**
  40.  * @defgroup apr_ring Ring Macro Implementations
  41.  * @ingroup APR 
  42.  * A ring is a kind of doubly-linked list that can be manipulated
  43.  * without knowing where its head is.
  44.  * @{
  45.  */
  46.  
  47. /**
  48.  * The Ring Element
  49.  *
  50.  * A ring element struct is linked to the other elements in the ring
  51.  * through its ring entry field, e.g.
  52.  * <pre>
  53.  *      struct my_element_t {
  54.  *          APR_RING_ENTRY(my_element_t) link;
  55.  *          int foo;
  56.  *          char *bar;
  57.  *      };
  58.  * </pre>
  59.  *
  60.  * An element struct may be put on more than one ring if it has more
  61.  * than one APR_RING_ENTRY field. Each APR_RING_ENTRY has a corresponding
  62.  * APR_RING_HEAD declaration.
  63.  *
  64.  * @warning For strict C standards compliance you should put the APR_RING_ENTRY
  65.  * first in the element struct unless the head is always part of a larger
  66.  * object with enough earlier fields to accommodate the offsetof() used
  67.  * to compute the ring sentinel below. You can usually ignore this caveat.
  68.  */
  69. #define APR_RING_ENTRY(elem)                        \
  70.     struct {                                \
  71.     struct elem *next;                        \
  72.     struct elem *prev;                        \
  73.     }
  74.  
  75. /**
  76.  * The Ring Head
  77.  *
  78.  * Each ring is managed via its head, which is a struct declared like this:
  79.  * <pre>
  80.  *      APR_RING_HEAD(my_ring_t, my_element_t);
  81.  *      struct my_ring_t ring, *ringp;
  82.  * </pre>
  83.  *
  84.  * This struct looks just like the element link struct so that we can
  85.  * be sure that the typecasting games will work as expected.
  86.  *
  87.  * The first element in the ring is next after the head, and the last
  88.  * element is just before the head.
  89.  */
  90. #define APR_RING_HEAD(head, elem)                    \
  91.     struct head {                            \
  92.     struct elem *next;                        \
  93.     struct elem *prev;                        \
  94.     }
  95.  
  96. /**
  97.  * The Ring Sentinel
  98.  *
  99.  * This is the magic pointer value that occurs before the first and
  100.  * after the last elements in the ring, computed from the address of
  101.  * the ring's head.  The head itself isn't an element, but in order to
  102.  * get rid of all the special cases when dealing with the ends of the
  103.  * ring, we play typecasting games to make it look like one.
  104.  *
  105.  * Here is a diagram to illustrate the arrangements of the next and
  106.  * prev pointers of each element in a single ring. Note that they point
  107.  * to the start of each element, not to the APR_RING_ENTRY structure.
  108.  *
  109.  * <pre>
  110.  *     +->+------+<-+  +->+------+<-+  +->+------+<-+
  111.  *     |  |struct|  |  |  |struct|  |  |  |struct|  |
  112.  *    /   | elem |   \/   | elem |   \/   | elem |  \
  113.  * ...    |      |   /\   |      |   /\   |      |   ...
  114.  *        +------+  |  |  +------+  |  |  +------+
  115.  *   ...--|prev  |  |  +--|ring  |  |  +--|prev  |
  116.  *        |  next|--+     | entry|--+     |  next|--...
  117.  *        +------+        +------+        +------+
  118.  *        | etc. |        | etc. |        | etc. |
  119.  *        :      :        :      :        :      :
  120.  * </pre>
  121.  *
  122.  * The APR_RING_HEAD is nothing but a bare APR_RING_ENTRY. The prev
  123.  * and next pointers in the first and last elements don't actually
  124.  * point to the head, they point to a phantom place called the
  125.  * sentinel. Its value is such that last->next->next == first because
  126.  * the offset from the sentinel to the head's next pointer is the same
  127.  * as the offset from the start of an element to its next pointer.
  128.  * This also works in the opposite direction.
  129.  *
  130.  * <pre>
  131.  *        last                            first
  132.  *     +->+------+<-+  +->sentinel<-+  +->+------+<-+
  133.  *     |  |struct|  |  |            |  |  |struct|  |
  134.  *    /   | elem |   \/              \/   | elem |  \
  135.  * ...    |      |   /\              /\   |      |   ...
  136.  *        +------+  |  |  +------+  |  |  +------+
  137.  *   ...--|prev  |  |  +--|ring  |  |  +--|prev  |
  138.  *        |  next|--+     |  head|--+     |  next|--...
  139.  *        +------+        +------+        +------+
  140.  *        | etc. |                        | etc. |
  141.  *        :      :                        :      :
  142.  * </pre>
  143.  *
  144.  * Note that the offset mentioned above is different for each kind of
  145.  * ring that the element may be on, and each kind of ring has a unique
  146.  * name for its APR_RING_ENTRY in each element, and has its own type
  147.  * for its APR_RING_HEAD.
  148.  *
  149.  * Note also that if the offset is non-zero (which is required if an
  150.  * element has more than one APR_RING_ENTRY), the unreality of the
  151.  * sentinel may have bad implications on very perverse implementations
  152.  * of C -- see the warning in APR_RING_ENTRY.
  153.  *
  154.  * @param hp   The head of the ring
  155.  * @param elem The name of the element struct
  156.  * @param link The name of the APR_RING_ENTRY in the element struct
  157.  */
  158. #define APR_RING_SENTINEL(hp, elem, link)                \
  159.     (struct elem *)((char *)(hp) - APR_OFFSETOF(struct elem, link))
  160.  
  161. /**
  162.  * The first element of the ring
  163.  * @param hp   The head of the ring
  164.  */
  165. #define APR_RING_FIRST(hp)    (hp)->next
  166. /**
  167.  * The last element of the ring
  168.  * @param hp   The head of the ring
  169.  */
  170. #define APR_RING_LAST(hp)    (hp)->prev
  171. /**
  172.  * The next element in the ring
  173.  * @param ep   The current element
  174.  * @param link The name of the APR_RING_ENTRY in the element struct
  175.  */
  176. #define APR_RING_NEXT(ep, link)    (ep)->link.next
  177. /**
  178.  * The previous element in the ring
  179.  * @param ep   The current element
  180.  * @param link The name of the APR_RING_ENTRY in the element struct
  181.  */
  182. #define APR_RING_PREV(ep, link)    (ep)->link.prev
  183.  
  184.  
  185. /**
  186.  * Initialize a ring
  187.  * @param hp   The head of the ring
  188.  * @param elem The name of the element struct
  189.  * @param link The name of the APR_RING_ENTRY in the element struct
  190.  */
  191. #define APR_RING_INIT(hp, elem, link) do {                \
  192.     APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link);    \
  193.     APR_RING_LAST((hp))  = APR_RING_SENTINEL((hp), elem, link);    \
  194.     } while (0)
  195.  
  196. /**
  197.  * Determine if a ring is empty
  198.  * @param hp   The head of the ring
  199.  * @param elem The name of the element struct
  200.  * @param link The name of the APR_RING_ENTRY in the element struct
  201.  * @return true or false
  202.  */
  203. #define APR_RING_EMPTY(hp, elem, link)                    \
  204.     (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))
  205.  
  206. /**
  207.  * Initialize a singleton element
  208.  * @param ep   The element
  209.  * @param link The name of the APR_RING_ENTRY in the element struct
  210.  */
  211. #define APR_RING_ELEM_INIT(ep, link) do {                \
  212.     APR_RING_NEXT((ep), link) = (ep);                \
  213.     APR_RING_PREV((ep), link) = (ep);                \
  214.     } while (0)
  215.  
  216.  
  217. /**
  218.  * Splice the sequence ep1..epN into the ring before element lep
  219.  *   (..lep.. becomes ..ep1..epN..lep..)
  220.  * @warning This doesn't work for splicing before the first element or on
  221.  *   empty rings... see APR_RING_SPLICE_HEAD for one that does
  222.  * @param lep  Element in the ring to splice before
  223.  * @param ep1  First element in the sequence to splice in
  224.  * @param epN  Last element in the sequence to splice in
  225.  * @param link The name of the APR_RING_ENTRY in the element struct
  226.  */
  227. #define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do {        \
  228.     APR_RING_NEXT((epN), link) = (lep);                \
  229.     APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link);    \
  230.     APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1);    \
  231.     APR_RING_PREV((lep), link) = (epN);                \
  232.     } while (0)
  233.  
  234. /**
  235.  * Splice the sequence ep1..epN into the ring after element lep
  236.  *   (..lep.. becomes ..lep..ep1..epN..)
  237.  * @warning This doesn't work for splicing after the last element or on
  238.  *   empty rings... see APR_RING_SPLICE_TAIL for one that does
  239.  * @param lep  Element in the ring to splice after
  240.  * @param ep1  First element in the sequence to splice in
  241.  * @param epN  Last element in the sequence to splice in
  242.  * @param link The name of the APR_RING_ENTRY in the element struct
  243.  */
  244. #define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do {            \
  245.     APR_RING_PREV((ep1), link) = (lep);                \
  246.     APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link);    \
  247.     APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN);    \
  248.     APR_RING_NEXT((lep), link) = (ep1);                \
  249.     } while (0)
  250.  
  251. /**
  252.  * Insert the element nep into the ring before element lep
  253.  *   (..lep.. becomes ..nep..lep..)
  254.  * @warning This doesn't work for inserting before the first element or on
  255.  *   empty rings... see APR_RING_INSERT_HEAD for one that does
  256.  * @param lep  Element in the ring to insert before
  257.  * @param nep  Element to insert
  258.  * @param link The name of the APR_RING_ENTRY in the element struct
  259.  */
  260. #define APR_RING_INSERT_BEFORE(lep, nep, link)                \
  261.     APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)
  262.  
  263. /**
  264.  * Insert the element nep into the ring after element lep
  265.  *   (..lep.. becomes ..lep..nep..)
  266.  * @warning This doesn't work for inserting after the last element or on
  267.  *   empty rings... see APR_RING_INSERT_TAIL for one that does
  268.  * @param lep  Element in the ring to insert after
  269.  * @param nep  Element to insert
  270.  * @param link The name of the APR_RING_ENTRY in the element struct
  271.  */
  272. #define APR_RING_INSERT_AFTER(lep, nep, link)                \
  273.     APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)
  274.  
  275.  
  276. /**
  277.  * Splice the sequence ep1..epN into the ring before the first element
  278.  *   (..hp.. becomes ..hp..ep1..epN..)
  279.  * @param hp   Head of the ring
  280.  * @param ep1  First element in the sequence to splice in
  281.  * @param epN  Last element in the sequence to splice in
  282.  * @param elem The name of the element struct
  283.  * @param link The name of the APR_RING_ENTRY in the element struct
  284.  */
  285. #define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link)            \
  286.     APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link),    \
  287.                  (ep1), (epN), link)
  288.  
  289. /**
  290.  * Splice the sequence ep1..epN into the ring after the last element
  291.  *   (..hp.. becomes ..ep1..epN..hp..)
  292.  * @param hp   Head of the ring
  293.  * @param ep1  First element in the sequence to splice in
  294.  * @param epN  Last element in the sequence to splice in
  295.  * @param elem The name of the element struct
  296.  * @param link The name of the APR_RING_ENTRY in the element struct
  297.  */
  298. #define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link)            \
  299.     APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link),    \
  300.                  (ep1), (epN), link)
  301.  
  302. /**
  303.  * Insert the element nep into the ring before the first element
  304.  *   (..hp.. becomes ..hp..nep..)
  305.  * @param hp   Head of the ring
  306.  * @param nep  Element to insert
  307.  * @param elem The name of the element struct
  308.  * @param link The name of the APR_RING_ENTRY in the element struct
  309.  */
  310. #define APR_RING_INSERT_HEAD(hp, nep, elem, link)            \
  311.     APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)
  312.  
  313. /**
  314.  * Insert the element nep into the ring after the last element
  315.  *   (..hp.. becomes ..nep..hp..)
  316.  * @param hp   Head of the ring
  317.  * @param nep  Element to insert
  318.  * @param elem The name of the element struct
  319.  * @param link The name of the APR_RING_ENTRY in the element struct
  320.  */
  321. #define APR_RING_INSERT_TAIL(hp, nep, elem, link)            \
  322.     APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
  323.  
  324. /**
  325.  * Concatenate ring h2 onto the end of ring h1, leaving h2 empty.
  326.  * @param h1   Head of the ring to concatenate onto
  327.  * @param h2   Head of the ring to concatenate
  328.  * @param elem The name of the element struct
  329.  * @param link The name of the APR_RING_ENTRY in the element struct
  330.  */
  331. #define APR_RING_CONCAT(h1, h2, elem, link) do {            \
  332.     if (!APR_RING_EMPTY((h2), elem, link)) {            \
  333.         APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link),    \
  334.                   APR_RING_FIRST((h2)),            \
  335.                   APR_RING_LAST((h2)), link);        \
  336.         APR_RING_INIT((h2), elem, link);                \
  337.     }                                \
  338.     } while (0)
  339.  
  340. /**
  341.  * Prepend ring h2 onto the beginning of ring h1, leaving h2 empty.
  342.  * @param h1   Head of the ring to prepend onto
  343.  * @param h2   Head of the ring to prepend
  344.  * @param elem The name of the element struct
  345.  * @param link The name of the APR_RING_ENTRY in the element struct
  346.  */
  347. #define APR_RING_PREPEND(h1, h2, elem, link) do {            \
  348.     if (!APR_RING_EMPTY((h2), elem, link)) {            \
  349.         APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((h1), elem, link),    \
  350.                   APR_RING_FIRST((h2)),            \
  351.                   APR_RING_LAST((h2)), link);        \
  352.         APR_RING_INIT((h2), elem, link);                \
  353.     }                                \
  354.     } while (0)
  355.  
  356. /**
  357.  * Unsplice a sequence of elements from a ring
  358.  * @warning The unspliced sequence is left with dangling pointers at either end
  359.  * @param ep1  First element in the sequence to unsplice
  360.  * @param epN  Last element in the sequence to unsplice
  361.  * @param link The name of the APR_RING_ENTRY in the element struct
  362.  */
  363. #define APR_RING_UNSPLICE(ep1, epN, link) do {                \
  364.     APR_RING_NEXT(APR_RING_PREV((ep1), link), link) =        \
  365.              APR_RING_NEXT((epN), link);            \
  366.     APR_RING_PREV(APR_RING_NEXT((epN), link), link) =        \
  367.              APR_RING_PREV((ep1), link);            \
  368.     } while (0)
  369.  
  370. /**
  371.  * Remove a single element from a ring
  372.  * @warning The unspliced element is left with dangling pointers at either end
  373.  * @param ep   Element to remove
  374.  * @param link The name of the APR_RING_ENTRY in the element struct
  375.  */
  376. #define APR_RING_REMOVE(ep, link)                    \
  377.     APR_RING_UNSPLICE((ep), (ep), link)
  378.  
  379.  
  380. /**
  381.  * Iterate through a ring
  382.  * @param ep The current element
  383.  * @param hp The ring to iterate over
  384.  * @param elem The name of the element struct
  385.  * @param link The name of the APR_RING_ENTRY in the element struct
  386.  * @remark This is the same as either:
  387.  * <pre>
  388.  *    ep = APR_RING_FIRST(hp);
  389.  *     while (ep != APR_RING_SENTINEL(hp, elem, link)) {
  390.  *        ...
  391.  *         ep = APR_RING_NEXT(ep, link);
  392.  *     }
  393.  *   OR
  394.  *     for (ep = APR_RING_FIRST(hp);
  395.  *           ep != APR_RING_SENTINEL(hp, elem, link);
  396.  *           ep = APR_RING_NEXT(ep, link)) {
  397.  *        ...
  398.  *     }
  399.  * </pre>
  400.  * @warning Be aware that you cannot change the value of ep within
  401.  * the foreach loop, nor can you destroy the ring element it points to.
  402.  * Modifying the prev and next pointers of the element is dangerous
  403.  * but can be done if you're careful.  If you change ep's value or
  404.  * destroy the element it points to, then APR_RING_FOREACH
  405.  * will have no way to find out what element to use for its next
  406.  * iteration.  The reason for this can be seen by looking closely
  407.  * at the equivalent loops given in the tip above.  So, for example,
  408.  * if you are writing a loop that empties out a ring one element
  409.  * at a time, APR_RING_FOREACH just won't work for you.  Do it
  410.  * by hand, like so:
  411.  * <pre>
  412.  *      while (!APR_RING_EMPTY(hp, elem, link)) {
  413.  *          ep = APR_RING_FIRST(hp);
  414.  *          ...
  415.  *          APR_RING_REMOVE(ep, link);
  416.  *      }
  417.  * </pre>
  418.  * @deprecated This macro causes more headaches than it's worth.  Use
  419.  * one of the alternatives documented here instead; the clarity gained
  420.  * in what's really going on is well worth the extra line or two of code.
  421.  * This macro will be removed at some point in the future.
  422.  */
  423. #define APR_RING_FOREACH(ep, hp, elem, link)                \
  424.     for ((ep)  = APR_RING_FIRST((hp));                    \
  425.      (ep) != APR_RING_SENTINEL((hp), elem, link);            \
  426.      (ep)  = APR_RING_NEXT((ep), link))
  427.  
  428. /**
  429.  * Iterate through a ring backwards
  430.  * @param ep The current element
  431.  * @param hp The ring to iterate over
  432.  * @param elem The name of the element struct
  433.  * @param link The name of the APR_RING_ENTRY in the element struct
  434.  * @see APR_RING_FOREACH
  435.  */
  436. #define APR_RING_FOREACH_REVERSE(ep, hp, elem, link)            \
  437.     for ((ep)  = APR_RING_LAST((hp));                    \
  438.      (ep) != APR_RING_SENTINEL((hp), elem, link);            \
  439.      (ep)  = APR_RING_PREV((ep), link))
  440.  
  441.  
  442. /* Debugging tools: */
  443.  
  444. #ifdef APR_RING_DEBUG
  445. #include <stdio.h>
  446. #include <assert.h>
  447.  
  448. #define APR_RING_CHECK_ONE(msg, ptr)                    \
  449.     fprintf(stderr, "*** %s %p\n", msg, ptr)
  450.  
  451. #define APR_RING_CHECK(hp, elem, link, msg)                \
  452.     APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)
  453.  
  454. #define APR_RING_CHECK_ELEM(ep, elem, link, msg) do {            \
  455.     struct elem *start = (ep);                    \
  456.     struct elem *here = start;                    \
  457.     fprintf(stderr, "*** ring check start -- %s\n", msg);        \
  458.     do {                                \
  459.         fprintf(stderr, "\telem %p\n", here);            \
  460.         fprintf(stderr, "\telem->next %p\n",            \
  461.             APR_RING_NEXT(here, link));                \
  462.         fprintf(stderr, "\telem->prev %p\n",            \
  463.             APR_RING_PREV(here, link));                \
  464.         fprintf(stderr, "\telem->next->prev %p\n",            \
  465.             APR_RING_PREV(APR_RING_NEXT(here, link), link));    \
  466.         fprintf(stderr, "\telem->prev->next %p\n",            \
  467.             APR_RING_NEXT(APR_RING_PREV(here, link), link));    \
  468.         if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
  469.         fprintf(stderr, "\t*** elem->next->prev != elem\n");    \
  470.         break;                            \
  471.         }                                \
  472.         if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
  473.         fprintf(stderr, "\t*** elem->prev->next != elem\n");    \
  474.         break;                            \
  475.         }                                \
  476.         here = APR_RING_NEXT(here, link);                \
  477.     } while (here != start);                    \
  478.     fprintf(stderr, "*** ring check end\n");            \
  479.     } while (0)
  480.  
  481. #define APR_RING_CHECK_CONSISTENCY(hp, elem, link)            \
  482.     APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
  483.                     elem, link)
  484.  
  485. #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do {        \
  486.     struct elem *start = (ep);                    \
  487.     struct elem *here = start;                    \
  488.     do {                                \
  489.         assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
  490.         assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
  491.         here = APR_RING_NEXT(here, link);                \
  492.     } while (here != start);                    \
  493.     } while (0)
  494.  
  495. #else
  496. /**
  497.  * Print a single pointer value to STDERR
  498.  *   (This is a no-op unless APR_RING_DEBUG is defined.)
  499.  * @param msg Descriptive message
  500.  * @param ptr Pointer value to print
  501.  */
  502. #define APR_RING_CHECK_ONE(msg, ptr)
  503. /**
  504.  * Dump all ring pointers to STDERR, starting with the head and looping all
  505.  * the way around the ring back to the head.  Aborts if an inconsistency
  506.  * is found.
  507.  *   (This is a no-op unless APR_RING_DEBUG is defined.)
  508.  * @param hp   Head of the ring
  509.  * @param elem The name of the element struct
  510.  * @param link The name of the APR_RING_ENTRY in the element struct
  511.  * @param msg  Descriptive message
  512.  */
  513. #define APR_RING_CHECK(hp, elem, link, msg)
  514. /**
  515.  * Loops around a ring and checks all the pointers for consistency.  Pops
  516.  * an assertion if any inconsistency is found.  Same idea as APR_RING_CHECK()
  517.  * except that it's silent if all is well.
  518.  *   (This is a no-op unless APR_RING_DEBUG is defined.)
  519.  * @param hp   Head of the ring
  520.  * @param elem The name of the element struct
  521.  * @param link The name of the APR_RING_ENTRY in the element struct
  522.  */
  523. #define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
  524. /**
  525.  * Dump all ring pointers to STDERR, starting with the given element and
  526.  * looping all the way around the ring back to that element.  Aborts if
  527.  * an inconsistency is found.
  528.  *   (This is a no-op unless APR_RING_DEBUG is defined.)
  529.  * @param ep   The element
  530.  * @param elem The name of the element struct
  531.  * @param link The name of the APR_RING_ENTRY in the element struct
  532.  * @param msg  Descriptive message
  533.  */
  534. #define APR_RING_CHECK_ELEM(ep, elem, link, msg)
  535. /**
  536.  * Loops around a ring, starting with the given element, and checks all
  537.  * the pointers for consistency.  Pops an assertion if any inconsistency
  538.  * is found.  Same idea as APR_RING_CHECK_ELEM() except that it's silent
  539.  * if all is well.
  540.  *   (This is a no-op unless APR_RING_DEBUG is defined.)
  541.  * @param ep   The element
  542.  * @param elem The name of the element struct
  543.  * @param link The name of the APR_RING_ENTRY in the element struct
  544.  */
  545. #define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
  546. #endif
  547.  
  548. /** @} */ 
  549.  
  550. #endif /* !APR_RING_H */
  551.