1 #ifndef ASTERISK_LINKEDLISTS_H
2 #define ASTERISK_LINKEDLISTS_H
4 #include <asterisk/lock.h>
8 \brief A set of macros to manage forward-linked lists.
12 \brief Attempts to lock a list.
13 \param head This is a pointer to the list head structure
15 This macro attempts to place an exclusive lock in the
16 list head structure pointed to by head.
17 Returns non-zero on success, 0 on failure
19 #define AST_LIST_LOCK(head) \
20 ast_mutex_lock(&(head)->lock)
23 \brief Attempts to unlock a list.
24 \param head This is a pointer to the list head structure
26 This macro attempts to remove an exclusive lock from the
27 list head structure pointed to by head. If the list
28 was not locked by this thread, this macro has no effect.
30 #define AST_LIST_UNLOCK(head) \
31 ast_mutex_unlock(&(head)->lock)
34 \brief Defines a structure to be used to hold a list of specified type.
35 \param name This will be the name of the defined structure.
36 \param type This is the type of each list entry.
38 This macro creates a structure definition that can be used
39 to hold a list of the entries of type \a type. It does not actually
40 declare (allocate) a structure; to do that, either follow this
41 macro with the desired name of the instance you wish to declare,
42 or use the specified \a name to declare instances elsewhere. It is
43 frequently used as follows:
45 static AST_LIST_HEAD(entry_list, entry) entries;
47 This would define \a struct \a entry_list, and declare an instance of it named
48 \a entries, all intended to hold a list of type \a struct \a entry.
50 #define AST_LIST_HEAD(name, type) \
57 \brief Initializes a list head structure with a specified first entry.
58 \param head This is a pointer to the list head structure
59 \param entry pointer to the list entry that will become the head of the list
61 This macro initializes a list head structure by setting the head
62 entry to the supplied value and recreating the embedded lock.
64 #define AST_LIST_HEAD_SET(head,entry) do { \
65 (head)->first=(entry); \
66 ast_pthread_mutex_init(&(head)->lock,NULL); \
70 \brief Declare a forward link structure inside a list entry.
71 \param type This is the type of each list entry.
73 This macro declares a structure to be used to link list entries together.
74 It must be used inside the definition of the structure named in
79 AST_LIST_ENTRY(list_entry) list;
82 The field name \a list here is arbitrary, and can be anything you wish.
84 #define AST_LIST_ENTRY(type) \
90 \brief Returns the first entry contained in a list.
91 \param head This is a pointer to the list head structure
93 #define AST_LIST_FIRST(head) ((head)->first)
96 \brief Returns the next entry in the list after the given entry.
97 \param elm This is a pointer to the current entry.
98 \param field This is the name of the field (declared using AST_LIST_ENTRY())
99 used to link entries of this list together.
101 #define AST_LIST_NEXT(elm, field) ((elm)->field.next)
104 \brief Checks whether the specified list contains any entries.
105 \param head This is a pointer to the list head structure
107 Returns non-zero if the list has entries, zero if not.
109 #define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
112 \brief Loops over (traverses) the entries in a list.
113 \param head This is a pointer to the list head structure
114 \param var This is the name of the variable that will hold a pointer to the
115 current list entry on each iteration. It must be declared before calling
117 \param field This is the name of the field (declared using AST_LIST_ENTRY())
118 used to link entries of this list together.
120 This macro is use to loop over (traverse) the entries in a list. It uses a
121 \a for loop, and supplies the enclosed code with a pointer to each list
122 entry as it loops. It is typically used as follows:
124 static AST_LIST_HEAD(entry_list, list_entry) entries;
128 AST_LIST_ENTRY(list_entry) list;
131 struct list_entry *current;
133 AST_LIST_TRAVERSE(&entries, current, list) {
134 (do something with current here)
137 \warning If you modify the forward-link pointer contained in the \a current entry while
138 inside the loop, the behavior will be unpredictable. At a minimum, the following
139 macros will modify the forward-link pointer, and should not be used inside
140 AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
141 careful consideration of their consequences:
142 \li AST_LIST_NEXT() (when used as an lvalue)
143 \li AST_LIST_INSERT_AFTER()
144 \li AST_LIST_INSERT_HEAD()
145 \li AST_LIST_INSERT_TAIL()
147 #define AST_LIST_TRAVERSE(head,var,field) \
148 for((var) = (head)->first; (var); (var) = (var)->field.next)
151 \brief Initializes a list head structure.
152 \param head This is a pointer to the list head structure
154 This macro initializes a list head structure by setting the head
155 entry to \a NULL (empty list) and recreating the embedded lock.
157 #define AST_LIST_HEAD_INIT(head) { \
158 (head)->first = NULL; \
159 ast_pthread_mutex_init(&(head)->lock,NULL); \
163 \brief Inserts a list entry after a given entry.
164 \param listelm This is a pointer to the entry after which the new entry should
166 \param elm This is a pointer to the entry to be inserted.
167 \param field This is the name of the field (declared using AST_LIST_ENTRY())
168 used to link entries of this list together.
170 #define AST_LIST_INSERT_AFTER(listelm, elm, field) do { \
171 (elm)->field.next = (listelm)->field.next; \
172 (listelm)->field.next = (elm); \
176 \brief Inserts a list entry at the head of a list.
177 \param head This is a pointer to the list head structure
178 \param elm This is a pointer to the entry to be inserted.
179 \param field This is the name of the field (declared using AST_LIST_ENTRY())
180 used to link entries of this list together.
182 #define AST_LIST_INSERT_HEAD(head, elm, field) do { \
183 (elm)->field.next = (head)->first; \
184 (head)->first = (elm); \
188 \brief Inserts a list entry at the tail of a list.
189 \param head This is a pointer to the list head structure
190 \param elm This is a pointer to the entry to be inserted.
191 \param type This is the type of each list entry.
192 \param field This is the name of the field (declared using AST_LIST_ENTRY())
193 used to link entries of this list together.
195 #define AST_LIST_INSERT_TAIL(head, elm, type, field) do { \
196 struct type *curelm = (head)->first; \
198 AST_LIST_INSERT_HEAD(head, elm, field); \
200 while ( curelm->field.next!=NULL ) { \
201 curelm=curelm->field.next; \
203 AST_LIST_INSERT_AFTER(curelm,elm,field); \
208 \brief Removes and returns the head entry from a list.
209 \param head This is a pointer to the list head structure
210 \param type This is the type of each list entry.
211 \param field This is the name of the field (declared using AST_LIST_ENTRY())
212 used to link entries of this list together.
214 Removes the head entry from the list, and returns a pointer to it. The
215 forward-link pointer in the returned entry is \b not cleared.
217 #define AST_LIST_REMOVE_HEAD(head, type, field) ({ \
218 struct type *cur = (head)->first; \
219 (head)->first = (head)->first->field.next; \
224 \brief Removes a specific entry from a list.
225 \param head This is a pointer to the list head structure
226 \param elm This is a pointer to the entry to be removed.
227 \param type This is the type of each list entry.
228 \param field This is the name of the field (declared using AST_LIST_ENTRY())
229 used to link entries of this list together.
230 \warning The removed entry is \b not freed nor modified in any way.
232 #define AST_LIST_REMOVE(head, elm, type, field) do { \
233 if ((head)->first == (elm)) { \
234 AST_LIST_REMOVE_HEAD((head), type, field); \
237 struct type *curelm = (head)->first; \
238 while( curelm->field.next != (elm) ) \
239 curelm = curelm->field.next; \
240 curelm->field.next = \
241 curelm->field.next->field.next; \