1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251875Speter * contributor license agreements. See the NOTICE file distributed with 3251875Speter * this work for additional information regarding copyright ownership. 4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251875Speter * (the "License"); you may not use this file except in compliance with 6251875Speter * the License. You may obtain a copy of the License at 7251875Speter * 8251875Speter * http://www.apache.org/licenses/LICENSE-2.0 9251875Speter * 10251875Speter * Unless required by applicable law or agreed to in writing, software 11251875Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251875Speter * See the License for the specific language governing permissions and 14251875Speter * limitations under the License. 15251875Speter */ 16251875Speter 17251875Speter/* 18251875Speter * This code draws heavily from the 4.4BSD <sys/queue.h> macros 19251875Speter * and Dean Gaudet's "splim/ring.h". 20251875Speter * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h> 21251875Speter * <http://www.arctic.org/~dean/splim/> 22251875Speter * 23251875Speter * We'd use Dean's code directly if we could guarantee the 24251875Speter * availability of inline functions. 25251875Speter */ 26251875Speter 27251875Speter#ifndef APR_RING_H 28251875Speter#define APR_RING_H 29251875Speter 30251875Speter/** 31251875Speter * @file apr_ring.h 32251875Speter * @brief APR Rings 33251875Speter */ 34251875Speter 35251875Speter/* 36251875Speter * for offsetof() 37251875Speter */ 38251875Speter#include "apr_general.h" 39251875Speter 40251875Speter/** 41251875Speter * @defgroup apr_ring Ring Macro Implementations 42251875Speter * @ingroup APR 43251875Speter * A ring is a kind of doubly-linked list that can be manipulated 44251875Speter * without knowing where its head is. 45251875Speter * @{ 46251875Speter */ 47251875Speter 48251875Speter/** 49251875Speter * The Ring Element 50251875Speter * 51251875Speter * A ring element struct is linked to the other elements in the ring 52251875Speter * through its ring entry field, e.g. 53251875Speter * <pre> 54251875Speter * struct my_element_t { 55251875Speter * APR_RING_ENTRY(my_element_t) link; 56251875Speter * int foo; 57251875Speter * char *bar; 58251875Speter * }; 59251875Speter * </pre> 60251875Speter * 61251875Speter * An element struct may be put on more than one ring if it has more 62251875Speter * than one APR_RING_ENTRY field. Each APR_RING_ENTRY has a corresponding 63251875Speter * APR_RING_HEAD declaration. 64251875Speter * 65251875Speter * @warning For strict C standards compliance you should put the APR_RING_ENTRY 66251875Speter * first in the element struct unless the head is always part of a larger 67251875Speter * object with enough earlier fields to accommodate the offsetof() used 68251875Speter * to compute the ring sentinel below. You can usually ignore this caveat. 69251875Speter */ 70251875Speter#define APR_RING_ENTRY(elem) \ 71251875Speter struct { \ 72251875Speter struct elem * volatile next; \ 73251875Speter struct elem * volatile prev; \ 74251875Speter } 75251875Speter 76251875Speter/** 77251875Speter * The Ring Head 78251875Speter * 79251875Speter * Each ring is managed via its head, which is a struct declared like this: 80251875Speter * <pre> 81251875Speter * APR_RING_HEAD(my_ring_t, my_element_t); 82251875Speter * struct my_ring_t ring, *ringp; 83251875Speter * </pre> 84251875Speter * 85251875Speter * This struct looks just like the element link struct so that we can 86251875Speter * be sure that the typecasting games will work as expected. 87251875Speter * 88251875Speter * The first element in the ring is next after the head, and the last 89251875Speter * element is just before the head. 90251875Speter */ 91251875Speter#define APR_RING_HEAD(head, elem) \ 92251875Speter struct head { \ 93251875Speter struct elem * volatile next; \ 94251875Speter struct elem * volatile prev; \ 95251875Speter } 96251875Speter 97251875Speter/** 98251875Speter * The Ring Sentinel 99251875Speter * 100251875Speter * This is the magic pointer value that occurs before the first and 101251875Speter * after the last elements in the ring, computed from the address of 102251875Speter * the ring's head. The head itself isn't an element, but in order to 103251875Speter * get rid of all the special cases when dealing with the ends of the 104251875Speter * ring, we play typecasting games to make it look like one. 105251875Speter * 106251875Speter * Here is a diagram to illustrate the arrangements of the next and 107251875Speter * prev pointers of each element in a single ring. Note that they point 108251875Speter * to the start of each element, not to the APR_RING_ENTRY structure. 109251875Speter * 110251875Speter * <pre> 111251875Speter * +->+------+<-+ +->+------+<-+ +->+------+<-+ 112251875Speter * | |struct| | | |struct| | | |struct| | 113251875Speter * / | elem | \/ | elem | \/ | elem | \ 114251875Speter * ... | | /\ | | /\ | | ... 115251875Speter * +------+ | | +------+ | | +------+ 116251875Speter * ...--|prev | | +--|ring | | +--|prev | 117251875Speter * | next|--+ | entry|--+ | next|--... 118251875Speter * +------+ +------+ +------+ 119251875Speter * | etc. | | etc. | | etc. | 120251875Speter * : : : : : : 121251875Speter * </pre> 122251875Speter * 123251875Speter * The APR_RING_HEAD is nothing but a bare APR_RING_ENTRY. The prev 124251875Speter * and next pointers in the first and last elements don't actually 125251875Speter * point to the head, they point to a phantom place called the 126251875Speter * sentinel. Its value is such that last->next->next == first because 127251875Speter * the offset from the sentinel to the head's next pointer is the same 128251875Speter * as the offset from the start of an element to its next pointer. 129251875Speter * This also works in the opposite direction. 130251875Speter * 131251875Speter * <pre> 132251875Speter * last first 133251875Speter * +->+------+<-+ +->sentinel<-+ +->+------+<-+ 134251875Speter * | |struct| | | | | |struct| | 135251875Speter * / | elem | \/ \/ | elem | \ 136251875Speter * ... | | /\ /\ | | ... 137251875Speter * +------+ | | +------+ | | +------+ 138251875Speter * ...--|prev | | +--|ring | | +--|prev | 139251875Speter * | next|--+ | head|--+ | next|--... 140251875Speter * +------+ +------+ +------+ 141251875Speter * | etc. | | etc. | 142251875Speter * : : : : 143251875Speter * </pre> 144251875Speter * 145251875Speter * Note that the offset mentioned above is different for each kind of 146251875Speter * ring that the element may be on, and each kind of ring has a unique 147251875Speter * name for its APR_RING_ENTRY in each element, and has its own type 148251875Speter * for its APR_RING_HEAD. 149251875Speter * 150251875Speter * Note also that if the offset is non-zero (which is required if an 151251875Speter * element has more than one APR_RING_ENTRY), the unreality of the 152251875Speter * sentinel may have bad implications on very perverse implementations 153251875Speter * of C -- see the warning in APR_RING_ENTRY. 154251875Speter * 155251875Speter * @param hp The head of the ring 156251875Speter * @param elem The name of the element struct 157251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 158251875Speter */ 159251875Speter#define APR_RING_SENTINEL(hp, elem, link) \ 160251875Speter (struct elem *)((char *)(&(hp)->next) - APR_OFFSETOF(struct elem, link)) 161251875Speter 162251875Speter/** 163251875Speter * The first element of the ring 164251875Speter * @param hp The head of the ring 165251875Speter */ 166251875Speter#define APR_RING_FIRST(hp) (hp)->next 167251875Speter/** 168251875Speter * The last element of the ring 169251875Speter * @param hp The head of the ring 170251875Speter */ 171251875Speter#define APR_RING_LAST(hp) (hp)->prev 172251875Speter/** 173251875Speter * The next element in the ring 174251875Speter * @param ep The current element 175251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 176251875Speter */ 177251875Speter#define APR_RING_NEXT(ep, link) (ep)->link.next 178251875Speter/** 179251875Speter * The previous element in the ring 180251875Speter * @param ep The current element 181251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 182251875Speter */ 183251875Speter#define APR_RING_PREV(ep, link) (ep)->link.prev 184251875Speter 185251875Speter 186251875Speter/** 187251875Speter * Initialize a ring 188251875Speter * @param hp The head of the ring 189251875Speter * @param elem The name of the element struct 190251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 191251875Speter */ 192251875Speter#define APR_RING_INIT(hp, elem, link) do { \ 193251875Speter APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link); \ 194251875Speter APR_RING_LAST((hp)) = APR_RING_SENTINEL((hp), elem, link); \ 195251875Speter } while (0) 196251875Speter 197251875Speter/** 198251875Speter * Determine if a ring is empty 199251875Speter * @param hp The head of the ring 200251875Speter * @param elem The name of the element struct 201251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 202251875Speter * @return true or false 203251875Speter */ 204251875Speter#define APR_RING_EMPTY(hp, elem, link) \ 205251875Speter (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link)) 206251875Speter 207251875Speter/** 208251875Speter * Initialize a singleton element 209251875Speter * @param ep The element 210251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 211251875Speter */ 212251875Speter#define APR_RING_ELEM_INIT(ep, link) do { \ 213251875Speter APR_RING_NEXT((ep), link) = (ep); \ 214251875Speter APR_RING_PREV((ep), link) = (ep); \ 215251875Speter } while (0) 216251875Speter 217251875Speter 218251875Speter/** 219251875Speter * Splice the sequence ep1..epN into the ring before element lep 220251875Speter * (..lep.. becomes ..ep1..epN..lep..) 221251875Speter * @warning This doesn't work for splicing before the first element or on 222251875Speter * empty rings... see APR_RING_SPLICE_HEAD for one that does 223251875Speter * @param lep Element in the ring to splice before 224251875Speter * @param ep1 First element in the sequence to splice in 225251875Speter * @param epN Last element in the sequence to splice in 226251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 227251875Speter */ 228251875Speter#define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do { \ 229251875Speter APR_RING_NEXT((epN), link) = (lep); \ 230251875Speter APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link); \ 231251875Speter APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1); \ 232251875Speter APR_RING_PREV((lep), link) = (epN); \ 233251875Speter } while (0) 234251875Speter 235251875Speter/** 236251875Speter * Splice the sequence ep1..epN into the ring after element lep 237251875Speter * (..lep.. becomes ..lep..ep1..epN..) 238251875Speter * @warning This doesn't work for splicing after the last element or on 239251875Speter * empty rings... see APR_RING_SPLICE_TAIL for one that does 240251875Speter * @param lep Element in the ring to splice after 241251875Speter * @param ep1 First element in the sequence to splice in 242251875Speter * @param epN Last element in the sequence to splice in 243251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 244251875Speter */ 245251875Speter#define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do { \ 246251875Speter APR_RING_PREV((ep1), link) = (lep); \ 247251875Speter APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link); \ 248251875Speter APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN); \ 249251875Speter APR_RING_NEXT((lep), link) = (ep1); \ 250251875Speter } while (0) 251251875Speter 252251875Speter/** 253251875Speter * Insert the element nep into the ring before element lep 254251875Speter * (..lep.. becomes ..nep..lep..) 255251875Speter * @warning This doesn't work for inserting before the first element or on 256251875Speter * empty rings... see APR_RING_INSERT_HEAD for one that does 257251875Speter * @param lep Element in the ring to insert before 258251875Speter * @param nep Element to insert 259251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 260251875Speter */ 261251875Speter#define APR_RING_INSERT_BEFORE(lep, nep, link) \ 262251875Speter APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link) 263251875Speter 264251875Speter/** 265251875Speter * Insert the element nep into the ring after element lep 266251875Speter * (..lep.. becomes ..lep..nep..) 267251875Speter * @warning This doesn't work for inserting after the last element or on 268251875Speter * empty rings... see APR_RING_INSERT_TAIL for one that does 269251875Speter * @param lep Element in the ring to insert after 270251875Speter * @param nep Element to insert 271251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 272251875Speter */ 273251875Speter#define APR_RING_INSERT_AFTER(lep, nep, link) \ 274251875Speter APR_RING_SPLICE_AFTER((lep), (nep), (nep), link) 275251875Speter 276251875Speter 277251875Speter/** 278251875Speter * Splice the sequence ep1..epN into the ring before the first element 279251875Speter * (..hp.. becomes ..hp..ep1..epN..) 280251875Speter * @param hp Head of the ring 281251875Speter * @param ep1 First element in the sequence to splice in 282251875Speter * @param epN Last element in the sequence to splice in 283251875Speter * @param elem The name of the element struct 284251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 285251875Speter */ 286251875Speter#define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) \ 287251875Speter APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link), \ 288251875Speter (ep1), (epN), link) 289251875Speter 290251875Speter/** 291251875Speter * Splice the sequence ep1..epN into the ring after the last element 292251875Speter * (..hp.. becomes ..ep1..epN..hp..) 293251875Speter * @param hp Head of the ring 294251875Speter * @param ep1 First element in the sequence to splice in 295251875Speter * @param epN Last element in the sequence to splice in 296251875Speter * @param elem The name of the element struct 297251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 298251875Speter */ 299251875Speter#define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \ 300251875Speter APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link), \ 301251875Speter (ep1), (epN), link) 302251875Speter 303251875Speter/** 304251875Speter * Insert the element nep into the ring before the first element 305251875Speter * (..hp.. becomes ..hp..nep..) 306251875Speter * @param hp Head of the ring 307251875Speter * @param nep Element to insert 308251875Speter * @param elem The name of the element struct 309251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 310251875Speter */ 311251875Speter#define APR_RING_INSERT_HEAD(hp, nep, elem, link) \ 312251875Speter APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link) 313251875Speter 314251875Speter/** 315251875Speter * Insert the element nep into the ring after the last element 316251875Speter * (..hp.. becomes ..nep..hp..) 317251875Speter * @param hp Head of the ring 318251875Speter * @param nep Element to insert 319251875Speter * @param elem The name of the element struct 320251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 321251875Speter */ 322251875Speter#define APR_RING_INSERT_TAIL(hp, nep, elem, link) \ 323251875Speter APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link) 324251875Speter 325251875Speter/** 326251875Speter * Concatenate ring h2 onto the end of ring h1, leaving h2 empty. 327251875Speter * @param h1 Head of the ring to concatenate onto 328251875Speter * @param h2 Head of the ring to concatenate 329251875Speter * @param elem The name of the element struct 330251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 331251875Speter */ 332251875Speter#define APR_RING_CONCAT(h1, h2, elem, link) do { \ 333251875Speter if (!APR_RING_EMPTY((h2), elem, link)) { \ 334251875Speter APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link), \ 335251875Speter APR_RING_FIRST((h2)), \ 336251875Speter APR_RING_LAST((h2)), link); \ 337251875Speter APR_RING_INIT((h2), elem, link); \ 338251875Speter } \ 339251875Speter } while (0) 340251875Speter 341251875Speter/** 342251875Speter * Prepend ring h2 onto the beginning of ring h1, leaving h2 empty. 343251875Speter * @param h1 Head of the ring to prepend onto 344251875Speter * @param h2 Head of the ring to prepend 345251875Speter * @param elem The name of the element struct 346251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 347251875Speter */ 348251875Speter#define APR_RING_PREPEND(h1, h2, elem, link) do { \ 349251875Speter if (!APR_RING_EMPTY((h2), elem, link)) { \ 350251875Speter APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((h1), elem, link), \ 351251875Speter APR_RING_FIRST((h2)), \ 352251875Speter APR_RING_LAST((h2)), link); \ 353251875Speter APR_RING_INIT((h2), elem, link); \ 354251875Speter } \ 355251875Speter } while (0) 356251875Speter 357251875Speter/** 358251875Speter * Unsplice a sequence of elements from a ring 359251875Speter * @warning The unspliced sequence is left with dangling pointers at either end 360251875Speter * @param ep1 First element in the sequence to unsplice 361251875Speter * @param epN Last element in the sequence to unsplice 362251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 363251875Speter */ 364251875Speter#define APR_RING_UNSPLICE(ep1, epN, link) do { \ 365251875Speter APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \ 366251875Speter APR_RING_NEXT((epN), link); \ 367251875Speter APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \ 368251875Speter APR_RING_PREV((ep1), link); \ 369251875Speter } while (0) 370251875Speter 371251875Speter/** 372251875Speter * Remove a single element from a ring 373251875Speter * @warning The unspliced element is left with dangling pointers at either end 374251875Speter * @param ep Element to remove 375251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 376251875Speter */ 377251875Speter#define APR_RING_REMOVE(ep, link) \ 378251875Speter APR_RING_UNSPLICE((ep), (ep), link) 379251875Speter 380251875Speter/** 381251875Speter * Iterate over a ring 382251875Speter * @param ep The current element 383251875Speter * @param head The head of the ring 384251875Speter * @param elem The name of the element struct 385251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 386251875Speter */ 387251875Speter#define APR_RING_FOREACH(ep, head, elem, link) \ 388251875Speter for (ep = APR_RING_FIRST(head); \ 389251875Speter ep != APR_RING_SENTINEL(head, elem, link); \ 390251875Speter ep = APR_RING_NEXT(ep, link)) 391251875Speter 392251875Speter/** 393251875Speter * Iterate over a ring safe against removal of the current element 394251875Speter * @param ep1 The current element 395251875Speter * @param ep2 Iteration cursor 396251875Speter * @param head The head of the ring 397251875Speter * @param elem The name of the element struct 398251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 399251875Speter */ 400251875Speter#define APR_RING_FOREACH_SAFE(ep1, ep2, head, elem, link) \ 401251875Speter for (ep1 = APR_RING_FIRST(head), ep2 = APR_RING_NEXT(ep1, link); \ 402251875Speter ep1 != APR_RING_SENTINEL(head, elem, link); \ 403251875Speter ep1 = ep2, ep2 = APR_RING_NEXT(ep1, link)) 404251875Speter 405251875Speter/* Debugging tools: */ 406251875Speter 407251875Speter#ifdef APR_RING_DEBUG 408251875Speter#include <stdio.h> 409251875Speter#include <assert.h> 410251875Speter 411251875Speter#define APR_RING_CHECK_ONE(msg, ptr) \ 412251875Speter fprintf(stderr, "*** %s %p\n", msg, ptr) 413251875Speter 414251875Speter#define APR_RING_CHECK(hp, elem, link, msg) \ 415251875Speter APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg) 416251875Speter 417251875Speter#define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \ 418251875Speter struct elem *start = (ep); \ 419251875Speter struct elem *here = start; \ 420251875Speter fprintf(stderr, "*** ring check start -- %s\n", msg); \ 421251875Speter do { \ 422251875Speter fprintf(stderr, "\telem %p\n", here); \ 423251875Speter fprintf(stderr, "\telem->next %p\n", \ 424251875Speter APR_RING_NEXT(here, link)); \ 425251875Speter fprintf(stderr, "\telem->prev %p\n", \ 426251875Speter APR_RING_PREV(here, link)); \ 427251875Speter fprintf(stderr, "\telem->next->prev %p\n", \ 428251875Speter APR_RING_PREV(APR_RING_NEXT(here, link), link)); \ 429251875Speter fprintf(stderr, "\telem->prev->next %p\n", \ 430251875Speter APR_RING_NEXT(APR_RING_PREV(here, link), link)); \ 431251875Speter if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \ 432251875Speter fprintf(stderr, "\t*** elem->next->prev != elem\n"); \ 433251875Speter break; \ 434251875Speter } \ 435251875Speter if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \ 436251875Speter fprintf(stderr, "\t*** elem->prev->next != elem\n"); \ 437251875Speter break; \ 438251875Speter } \ 439251875Speter here = APR_RING_NEXT(here, link); \ 440251875Speter } while (here != start); \ 441251875Speter fprintf(stderr, "*** ring check end\n"); \ 442251875Speter } while (0) 443251875Speter 444251875Speter#define APR_RING_CHECK_CONSISTENCY(hp, elem, link) \ 445251875Speter APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\ 446251875Speter elem, link) 447251875Speter 448251875Speter#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do { \ 449251875Speter struct elem *start = (ep); \ 450251875Speter struct elem *here = start; \ 451251875Speter do { \ 452251875Speter assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \ 453251875Speter assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \ 454251875Speter here = APR_RING_NEXT(here, link); \ 455251875Speter } while (here != start); \ 456251875Speter } while (0) 457251875Speter 458251875Speter#else 459251875Speter/** 460251875Speter * Print a single pointer value to STDERR 461251875Speter * (This is a no-op unless APR_RING_DEBUG is defined.) 462251875Speter * @param msg Descriptive message 463251875Speter * @param ptr Pointer value to print 464251875Speter */ 465251875Speter#define APR_RING_CHECK_ONE(msg, ptr) 466251875Speter/** 467251875Speter * Dump all ring pointers to STDERR, starting with the head and looping all 468251875Speter * the way around the ring back to the head. Aborts if an inconsistency 469251875Speter * is found. 470251875Speter * (This is a no-op unless APR_RING_DEBUG is defined.) 471251875Speter * @param hp Head of the ring 472251875Speter * @param elem The name of the element struct 473251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 474251875Speter * @param msg Descriptive message 475251875Speter */ 476251875Speter#define APR_RING_CHECK(hp, elem, link, msg) 477251875Speter/** 478251875Speter * Loops around a ring and checks all the pointers for consistency. Pops 479251875Speter * an assertion if any inconsistency is found. Same idea as APR_RING_CHECK() 480251875Speter * except that it's silent if all is well. 481251875Speter * (This is a no-op unless APR_RING_DEBUG is defined.) 482251875Speter * @param hp Head of the ring 483251875Speter * @param elem The name of the element struct 484251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 485251875Speter */ 486251875Speter#define APR_RING_CHECK_CONSISTENCY(hp, elem, link) 487251875Speter/** 488251875Speter * Dump all ring pointers to STDERR, starting with the given element and 489251875Speter * looping all the way around the ring back to that element. Aborts if 490251875Speter * an inconsistency is found. 491251875Speter * (This is a no-op unless APR_RING_DEBUG is defined.) 492251875Speter * @param ep The element 493251875Speter * @param elem The name of the element struct 494251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 495251875Speter * @param msg Descriptive message 496251875Speter */ 497251875Speter#define APR_RING_CHECK_ELEM(ep, elem, link, msg) 498251875Speter/** 499251875Speter * Loops around a ring, starting with the given element, and checks all 500251875Speter * the pointers for consistency. Pops an assertion if any inconsistency 501251875Speter * is found. Same idea as APR_RING_CHECK_ELEM() except that it's silent 502251875Speter * if all is well. 503251875Speter * (This is a no-op unless APR_RING_DEBUG is defined.) 504251875Speter * @param ep The element 505251875Speter * @param elem The name of the element struct 506251875Speter * @param link The name of the APR_RING_ENTRY in the element struct 507251875Speter */ 508251875Speter#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) 509251875Speter#endif 510251875Speter 511251875Speter/** @} */ 512251875Speter 513251875Speter#endif /* !APR_RING_H */ 514