make really loud unable to communicate with peerinfo messages go away
[oweals/gnunet.git] / src / nat / bsdqueue.h
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file nat/bsdqueue.h
23  * @brief BSD implementation of simple lists
24  *
25  * @author Milan Bouchet-Valat
26  */
27
28 /*
29  * Copyright (c) 1991, 1993
30  *      The Regents of the University of California.  All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  * 1. Redistributions of source code must retain the above copyright
36  *    notice, this list of conditions and the following disclaimer.
37  * 2. Redistributions in binary form must reproduce the above copyright
38  *    notice, this list of conditions and the following disclaimer in the
39  *    documentation and/or other materials provided with the distribution.
40  * 3. Neither the name of the University nor the names of its contributors
41  *    may be used to endorse or promote products derived from this software
42  *    without specific prior written permission.
43  *
44  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54  * SUCH DAMAGE.
55  *
56  *      @(#)queue.h     8.5 (Berkeley) 8/20/94
57  */
58
59 #ifndef BSD_QUEUE_H
60 #define BSD_QUEUE_H
61
62 /*
63  * A list is headed by a single forward pointer (or an array of forward
64  * pointers for a hash table header). The elements are doubly linked
65  * so that an arbitrary element can be removed without a need to
66  * traverse the list. New elements can be added to the list before
67  * or after an existing element or at the head of the list. A list
68  * may only be traversed in the forward direction.
69  */
70
71 #ifdef QUEUE_MACRO_DEBUG
72 #define _Q_INVALIDATE(a) (a) = ((void *)-1)
73 #else
74 #define _Q_INVALIDATE(a)
75 #endif
76
77 /*
78  * List definitions.
79  */
80 #define LIST_HEAD(name, type)                                           \
81 struct name {                                                           \
82         struct type *lh_first;  /* first element */                     \
83 }
84
85 #define LIST_HEAD_INITIALIZER(head)                                     \
86         { NULL }
87
88 #define LIST_ENTRY(type)                                                \
89 struct {                                                                \
90         struct type *le_next;   /* next element */                      \
91         struct type **le_prev;  /* address of previous next element */  \
92 }
93
94 /*
95  * List access methods
96  */
97 #define LIST_FIRST(head)                ((head)->lh_first)
98 #define LIST_END(head)                  NULL
99 #define LIST_EMPTY(head)                (LIST_FIRST(head) == LIST_END(head))
100 #define LIST_NEXT(elm, field)           ((elm)->field.le_next)
101
102 #define LIST_FOREACH(var, head, field)                                  \
103         for((var) = LIST_FIRST(head);                                   \
104             (var)!= LIST_END(head);                                     \
105             (var) = LIST_NEXT(var, field))
106
107 /*
108  * List functions.
109  */
110 #define LIST_INIT(head) do {                                            \
111         LIST_FIRST(head) = LIST_END(head);                              \
112 } while (0)
113
114 #define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
115         if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
116                 (listelm)->field.le_next->field.le_prev =               \
117                     &(elm)->field.le_next;                              \
118         (listelm)->field.le_next = (elm);                               \
119         (elm)->field.le_prev = &(listelm)->field.le_next;               \
120 } while (0)
121
122 #define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
123         (elm)->field.le_prev = (listelm)->field.le_prev;                \
124         (elm)->field.le_next = (listelm);                               \
125         *(listelm)->field.le_prev = (elm);                              \
126         (listelm)->field.le_prev = &(elm)->field.le_next;               \
127 } while (0)
128
129 #define LIST_INSERT_HEAD(head, elm, field) do {                         \
130         if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
131                 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
132         (head)->lh_first = (elm);                                       \
133         (elm)->field.le_prev = &(head)->lh_first;                       \
134 } while (0)
135
136 #define LIST_REMOVE(elm, field) do {                                    \
137         if ((elm)->field.le_next != NULL)                               \
138                 (elm)->field.le_next->field.le_prev =                   \
139                     (elm)->field.le_prev;                               \
140         *(elm)->field.le_prev = (elm)->field.le_next;                   \
141         _Q_INVALIDATE((elm)->field.le_prev);                            \
142         _Q_INVALIDATE((elm)->field.le_next);                            \
143 } while (0)
144
145 #define LIST_REPLACE(elm, elm2, field) do {                             \
146         if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)     \
147                 (elm2)->field.le_next->field.le_prev =                  \
148                     &(elm2)->field.le_next;                             \
149         (elm2)->field.le_prev = (elm)->field.le_prev;                   \
150         *(elm2)->field.le_prev = (elm2);                                \
151         _Q_INVALIDATE((elm)->field.le_prev);                            \
152         _Q_INVALIDATE((elm)->field.le_next);                            \
153 } while (0)
154
155 #endif
156
157 /* end of bsd-queue.h */