tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

queue.h (11732B)


      1 /*
      2 * Copyright (c) 1991, 1993
      3 *  The Regents of the University of California.  All rights reserved.
      4 *
      5 * Redistribution and use in source and binary forms, with or without
      6 * modification, are permitted provided that the following conditions
      7 * are met:
      8 * 1. Redistributions of source code must retain the above copyright
      9 *    notice, this list of conditions and the following disclaimer.
     10 * 2. Redistributions in binary form must reproduce the above copyright
     11 *    notice, this list of conditions and the following disclaimer in the
     12 *    documentation and/or other materials provided with the distribution.
     13 * 3. ***REMOVED*** - see
     14 *    ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
     15 * 4. Neither the name of the University nor the names of its contributors
     16 *    may be used to endorse or promote products derived from this software
     17 *    without specific prior written permission.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29 * SUCH DAMAGE.
     30 *
     31 *  @(#)queue.h 8.3 (Berkeley) 12/13/93
     32 */
     33 
     34 #ifndef _QUEUE_H_
     35 #define _QUEUE_H_
     36 
     37 /*
     38 * This file defines three types of data structures: lists, tail queues,
     39 * and circular queues.
     40 *
     41 * A list is headed by a single forward pointer (or an array of forward
     42 * pointers for a hash table header). The elements are doubly linked
     43 * so that an arbitrary element can be removed without a need to
     44 * traverse the list. New elements can be added to the list after
     45 * an existing element or at the head of the list. A list may only be
     46 * traversed in the forward direction.
     47 *
     48 * A tail queue is headed by a pair of pointers, one to the head of the
     49 * list and the other to the tail of the list. The elements are doubly
     50 * linked so that an arbitrary element can be removed without a need to
     51 * traverse the list. New elements can be added to the list after
     52 * an existing element, at the head of the list, or at the end of the
     53 * list. A tail queue may only be traversed in the forward direction.
     54 *
     55 * A circle queue is headed by a pair of pointers, one to the head of the
     56 * list and the other to the tail of the list. The elements are doubly
     57 * linked so that an arbitrary element can be removed without a need to
     58 * traverse the list. New elements can be added to the list before or after
     59 * an existing element, at the head of the list, or at the end of the list.
     60 * A circle queue may be traversed in either direction, but has a more
     61 * complex end of list detection.
     62 *
     63 * For details on the use of these macros, see the queue(3) manual page.
     64 */
     65 
     66 /*
     67 * List definitions.
     68 */
     69 #define LIST_HEAD(name, type)                      \
     70    struct name {                                  \
     71        struct type *lh_first; /* first element */ \
     72    }
     73 
     74 #define LIST_ENTRY(type)                                              \
     75    struct {                                                          \
     76        struct type *le_next;  /* next element */                     \
     77        struct type **le_prev; /* address of previous next element */ \
     78    }
     79 
     80 /*
     81 * List functions.
     82 */
     83 #define LIST_INIT(head)          \
     84    {                            \
     85        (head)->lh_first = NULL; \
     86    }
     87 
     88 #define LIST_INSERT_AFTER(listelm, elm, field)                         \
     89    {                                                                  \
     90        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
     91            (listelm)->field.le_next->field.le_prev =                  \
     92                &(elm)->field.le_next;                                 \
     93        (listelm)->field.le_next = (elm);                              \
     94        (elm)->field.le_prev = &(listelm)->field.le_next;              \
     95    }
     96 
     97 #define LIST_INSERT_HEAD(head, elm, field)                           \
     98    {                                                                \
     99        if (((elm)->field.le_next = (head)->lh_first) != NULL)       \
    100            (head)->lh_first->field.le_prev = &(elm)->field.le_next; \
    101        (head)->lh_first = (elm);                                    \
    102        (elm)->field.le_prev = &(head)->lh_first;                    \
    103    }
    104 
    105 #define LIST_REMOVE(elm, field)                       \
    106    {                                                 \
    107        if ((elm)->field.le_next != NULL)             \
    108            (elm)->field.le_next->field.le_prev =     \
    109                (elm)->field.le_prev;                 \
    110        *(elm)->field.le_prev = (elm)->field.le_next; \
    111    }
    112 
    113 /*
    114 * Tail queue definitions.
    115 */
    116 #define TAILQ_HEAD(name, type)                                  \
    117    struct name {                                               \
    118        struct type *tqh_first; /* first element */             \
    119        struct type **tqh_last; /* addr of last next element */ \
    120    }
    121 
    122 #define TAILQ_ENTRY(type)                                              \
    123    struct {                                                           \
    124        struct type *tqe_next;  /* next element */                     \
    125        struct type **tqe_prev; /* address of previous next element */ \
    126    }
    127 
    128 /*
    129 * Tail queue functions.
    130 */
    131 #define TAILQ_INIT(head)                       \
    132    {                                          \
    133        (head)->tqh_first = NULL;              \
    134        (head)->tqh_last = &(head)->tqh_first; \
    135    }
    136 
    137 #define TAILQ_INSERT_HEAD(head, elm, field)                      \
    138    {                                                            \
    139        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
    140            (elm)->field.tqe_next->field.tqe_prev =              \
    141                &(elm)->field.tqe_next;                          \
    142        else                                                     \
    143            (head)->tqh_last = &(elm)->field.tqe_next;           \
    144        (head)->tqh_first = (elm);                               \
    145        (elm)->field.tqe_prev = &(head)->tqh_first;              \
    146    }
    147 
    148 #define TAILQ_INSERT_TAIL(head, elm, field)        \
    149    {                                              \
    150        (elm)->field.tqe_next = NULL;              \
    151        (elm)->field.tqe_prev = (head)->tqh_last;  \
    152        *(head)->tqh_last = (elm);                 \
    153        (head)->tqh_last = &(elm)->field.tqe_next; \
    154    }
    155 
    156 #define TAILQ_INSERT_AFTER(head, listelm, elm, field)                    \
    157    {                                                                    \
    158        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL) \
    159            (elm)->field.tqe_next->field.tqe_prev =                      \
    160                &(elm)->field.tqe_next;                                  \
    161        else                                                             \
    162            (head)->tqh_last = &(elm)->field.tqe_next;                   \
    163        (listelm)->field.tqe_next = (elm);                               \
    164        (elm)->field.tqe_prev = &(listelm)->field.tqe_next;              \
    165    }
    166 
    167 #define TAILQ_REMOVE(head, elm, field)                  \
    168    {                                                   \
    169        if (((elm)->field.tqe_next) != NULL)            \
    170            (elm)->field.tqe_next->field.tqe_prev =     \
    171                (elm)->field.tqe_prev;                  \
    172        else                                            \
    173            (head)->tqh_last = (elm)->field.tqe_prev;   \
    174        *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
    175    }
    176 
    177 /*
    178 * Circular queue definitions.
    179 */
    180 #define CIRCLEQ_HEAD(name, type)                    \
    181    struct name {                                   \
    182        struct type *cqh_first; /* first element */ \
    183        struct type *cqh_last;  /* last element */  \
    184    }
    185 
    186 #define CIRCLEQ_ENTRY(type)                           \
    187    struct {                                          \
    188        struct type *cqe_next; /* next element */     \
    189        struct type *cqe_prev; /* previous element */ \
    190    }
    191 
    192 /*
    193 * Circular queue functions.
    194 */
    195 #define CIRCLEQ_INIT(head)                  \
    196    {                                       \
    197        (head)->cqh_first = (void *)(head); \
    198        (head)->cqh_last = (void *)(head);  \
    199    }
    200 
    201 #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field)        \
    202    {                                                          \
    203        (elm)->field.cqe_next = (listelm)->field.cqe_next;     \
    204        (elm)->field.cqe_prev = (listelm);                     \
    205        if ((listelm)->field.cqe_next == (void *)(head))       \
    206            (head)->cqh_last = (elm);                          \
    207        else                                                   \
    208            (listelm)->field.cqe_next->field.cqe_prev = (elm); \
    209        (listelm)->field.cqe_next = (elm);                     \
    210    }
    211 
    212 #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field)       \
    213    {                                                          \
    214        (elm)->field.cqe_next = (listelm);                     \
    215        (elm)->field.cqe_prev = (listelm)->field.cqe_prev;     \
    216        if ((listelm)->field.cqe_prev == (void *)(head))       \
    217            (head)->cqh_first = (elm);                         \
    218        else                                                   \
    219            (listelm)->field.cqe_prev->field.cqe_next = (elm); \
    220        (listelm)->field.cqe_prev = (elm);                     \
    221    }
    222 
    223 #define CIRCLEQ_INSERT_HEAD(head, elm, field)          \
    224    {                                                  \
    225        (elm)->field.cqe_next = (head)->cqh_first;     \
    226        (elm)->field.cqe_prev = (void *)(head);        \
    227        if ((head)->cqh_last == (void *)(head))        \
    228            (head)->cqh_last = (elm);                  \
    229        else                                           \
    230            (head)->cqh_first->field.cqe_prev = (elm); \
    231        (head)->cqh_first = (elm);                     \
    232    }
    233 
    234 #define CIRCLEQ_INSERT_TAIL(head, elm, field)         \
    235    {                                                 \
    236        (elm)->field.cqe_next = (void *)(head);       \
    237        (elm)->field.cqe_prev = (head)->cqh_last;     \
    238        if ((head)->cqh_first == (void *)(head))      \
    239            (head)->cqh_first = (elm);                \
    240        else                                          \
    241            (head)->cqh_last->field.cqe_next = (elm); \
    242        (head)->cqh_last = (elm);                     \
    243    }
    244 
    245 #define CIRCLEQ_REMOVE(head, elm, field)               \
    246    {                                                  \
    247        if ((elm)->field.cqe_next == (void *)(head))   \
    248            (head)->cqh_last = (elm)->field.cqe_prev;  \
    249        else                                           \
    250            (elm)->field.cqe_next->field.cqe_prev =    \
    251                (elm)->field.cqe_prev;                 \
    252        if ((elm)->field.cqe_prev == (void *)(head))   \
    253            (head)->cqh_first = (elm)->field.cqe_next; \
    254        else                                           \
    255            (elm)->field.cqe_prev->field.cqe_next =    \
    256                (elm)->field.cqe_next;                 \
    257    }
    258 #endif /* !_QUEUE_H_ */