Wed Jan 8 2020 09:49:46

Asterisk developer's documentation


dlinkedlists.h
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007, Digium, Inc.
5  *
6  * Steve Murphy <murf@digium.com>
7  *
8  * Doubly-Linked List Macros--
9  * Based on linkedlists.h (to the point of plagiarism!), which is by:
10  *
11  * Mark Spencer <markster@digium.com>
12  * Kevin P. Fleming <kpfleming@digium.com>
13  *
14  * See http://www.asterisk.org for more information about
15  * the Asterisk project. Please do not directly contact
16  * any of the maintainers of this project for assistance;
17  * the project provides a web site, mailing lists and IRC
18  * channels for your use.
19  *
20  * This program is free software, distributed under the terms of
21  * the GNU General Public License Version 2. See the LICENSE file
22  * at the top of the source tree.
23  */
24 
25 #ifndef ASTERISK_DLINKEDLISTS_H
26 #define ASTERISK_DLINKEDLISTS_H
27 
28 #include "asterisk/lock.h"
29 
30 /*!
31  \file dlinkedlists.h
32  \brief A set of macros to manage doubly-linked lists.
33 */
34 
35 /*!
36  \brief Locks a list.
37  \param head This is a pointer to the list head structure
38 
39  This macro attempts to place an exclusive lock in the
40  list head structure pointed to by head.
41  \retval 0 on success
42  \retval non-zero on failure
43  \since 1.6.1
44 */
45 #define AST_DLLIST_LOCK(head) \
46  ast_mutex_lock(&(head)->lock)
47 
48 /*!
49  \brief Write locks a list.
50  \param head This is a pointer to the list head structure
51 
52  This macro attempts to place an exclusive write lock in the
53  list head structure pointed to by head.
54  \retval 0 on success
55  \retval non-zero on failure
56  \since 1.6.1
57 */
58 #define AST_RWDLLIST_WRLOCK(head) \
59  ast_rwlock_wrlock(&(head)->lock)
60 
61 /*!
62  \brief Read locks a list.
63  \param head This is a pointer to the list head structure
64 
65  This macro attempts to place a read lock in the
66  list head structure pointed to by head.
67  \retval 0 on success
68  \retval non-zero on failure
69  \since 1.6.1
70 */
71 #define AST_RWDLLIST_RDLOCK(head) \
72  ast_rwlock_rdlock(&(head)->lock)
73 
74 /*!
75  \brief Locks a list, without blocking if the list is locked.
76  \param head This is a pointer to the list head structure
77 
78  This macro attempts to place an exclusive lock in the
79  list head structure pointed to by head.
80  \retval 0 on success
81  \retval non-zero on failure
82  \since 1.6.1
83 */
84 #define AST_DLLIST_TRYLOCK(head) \
85  ast_mutex_trylock(&(head)->lock)
86 
87 /*!
88  \brief Write locks a list, without blocking if the list is locked.
89  \param head This is a pointer to the list head structure
90 
91  This macro attempts to place an exclusive write lock in the
92  list head structure pointed to by head.
93  \retval 0 on success
94  \retval non-zero on failure
95  \since 1.6.1
96 */
97 #define AST_RWDLLIST_TRYWRLOCK(head) \
98  ast_rwlock_trywrlock(&(head)->lock)
99 
100 /*!
101  \brief Read locks a list, without blocking if the list is locked.
102  \param head This is a pointer to the list head structure
103 
104  This macro attempts to place a read lock in the
105  list head structure pointed to by head.
106  \retval 0 on success
107  \retval non-zero on failure
108  \since 1.6.1
109 */
110 #define AST_RWDLLIST_TRYRDLOCK(head) \
111  ast_rwlock_tryrdlock(&(head)->lock)
112 
113 /*!
114  \brief Attempts to unlock a list.
115  \param head This is a pointer to the list head structure
116 
117  This macro attempts to remove an exclusive lock from the
118  list head structure pointed to by head. If the list
119  was not locked by this thread, this macro has no effect.
120  \since 1.6.1
121 */
122 #define AST_DLLIST_UNLOCK(head) \
123  ast_mutex_unlock(&(head)->lock)
124 
125 /*!
126  \brief Attempts to unlock a read/write based list.
127  \param head This is a pointer to the list head structure
128 
129  This macro attempts to remove a read or write lock from the
130  list head structure pointed to by head. If the list
131  was not locked by this thread, this macro has no effect.
132  \since 1.6.1
133 */
134 #define AST_RWDLLIST_UNLOCK(head) \
135  ast_rwlock_unlock(&(head)->lock)
136 
137 /*!
138  \brief Defines a structure to be used to hold a list of specified type.
139  \param name This will be the name of the defined structure.
140  \param type This is the type of each list entry.
141 
142  This macro creates a structure definition that can be used
143  to hold a list of the entries of type \a type. It does not actually
144  declare (allocate) a structure; to do that, either follow this
145  macro with the desired name of the instance you wish to declare,
146  or use the specified \a name to declare instances elsewhere.
147 
148  Example usage:
149  \code
150  static AST_DLLIST_HEAD(entry_list, entry) entries;
151  \endcode
152 
153  This would define \c struct \c entry_list, and declare an instance of it named
154  \a entries, all intended to hold a list of type \c struct \c entry.
155  \since 1.6.1
156 */
157 #define AST_DLLIST_HEAD(name, type) \
158 struct name { \
159  struct type *first; \
160  struct type *last; \
161  ast_mutex_t lock; \
162 }
163 
164 /*!
165  \brief Defines a structure to be used to hold a read/write list of specified type.
166  \param name This will be the name of the defined structure.
167  \param type This is the type of each list entry.
168 
169  This macro creates a structure definition that can be used
170  to hold a list of the entries of type \a type. It does not actually
171  declare (allocate) a structure; to do that, either follow this
172  macro with the desired name of the instance you wish to declare,
173  or use the specified \a name to declare instances elsewhere.
174 
175  Example usage:
176  \code
177  static AST_RWDLLIST_HEAD(entry_list, entry) entries;
178  \endcode
179 
180  This would define \c struct \c entry_list, and declare an instance of it named
181  \a entries, all intended to hold a list of type \c struct \c entry.
182  \since 1.6.1
183 */
184 #define AST_RWDLLIST_HEAD(name, type) \
185 struct name { \
186  struct type *first; \
187  struct type *last; \
188  ast_rwlock_t lock; \
189 }
190 
191 /*!
192  \brief Defines a structure to be used to hold a list of specified type (with no lock).
193  \param name This will be the name of the defined structure.
194  \param type This is the type of each list entry.
195 
196  This macro creates a structure definition that can be used
197  to hold a list of the entries of type \a type. It does not actually
198  declare (allocate) a structure; to do that, either follow this
199  macro with the desired name of the instance you wish to declare,
200  or use the specified \a name to declare instances elsewhere.
201 
202  Example usage:
203  \code
204  static AST_DLLIST_HEAD_NOLOCK(entry_list, entry) entries;
205  \endcode
206 
207  This would define \c struct \c entry_list, and declare an instance of it named
208  \a entries, all intended to hold a list of type \c struct \c entry.
209  \since 1.6.1
210 */
211 #define AST_DLLIST_HEAD_NOLOCK(name, type) \
212 struct name { \
213  struct type *first; \
214  struct type *last; \
215 }
216 
217 /*!
218  \brief Defines initial values for a declaration of AST_DLLIST_HEAD
219  \since 1.6.1
220 */
221 #define AST_DLLIST_HEAD_INIT_VALUE { \
222  .first = NULL, \
223  .last = NULL, \
224  .lock = AST_MUTEX_INIT_VALUE, \
225  }
226 
227 /*!
228  \brief Defines initial values for a declaration of AST_RWDLLIST_HEAD
229  \since 1.6.1
230 */
231 #define AST_RWDLLIST_HEAD_INIT_VALUE { \
232  .first = NULL, \
233  .last = NULL, \
234  .lock = AST_RWLOCK_INIT_VALUE, \
235  }
236 
237 /*!
238  \brief Defines initial values for a declaration of AST_DLLIST_HEAD_NOLOCK
239  \since 1.6.1
240 */
241 #define AST_DLLIST_HEAD_NOLOCK_INIT_VALUE { \
242  .first = NULL, \
243  .last = NULL, \
244  }
245 
246 /*!
247  \brief Defines a structure to be used to hold a list of specified type, statically initialized.
248  \param name This will be the name of the defined structure.
249  \param type This is the type of each list entry.
250 
251  This macro creates a structure definition that can be used
252  to hold a list of the entries of type \a type, and allocates an instance
253  of it, initialized to be empty.
254 
255  Example usage:
256  \code
257  static AST_DLLIST_HEAD_STATIC(entry_list, entry);
258  \endcode
259 
260  This would define \c struct \c entry_list, intended to hold a list of
261  type \c struct \c entry.
262  \since 1.6.1
263 */
264 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
265 #define AST_DLLIST_HEAD_STATIC(name, type) \
266 struct name { \
267  struct type *first; \
268  struct type *last; \
269  ast_mutex_t lock; \
270 } name; \
271 static void __attribute__((constructor)) __init_##name(void) \
272 { \
273  AST_DLLIST_HEAD_INIT(&name); \
274 } \
275 static void __attribute__((destructor)) __fini_##name(void) \
276 { \
277  AST_DLLIST_HEAD_DESTROY(&name); \
278 } \
279 struct __dummy_##name
280 #else
281 #define AST_DLLIST_HEAD_STATIC(name, type) \
282 struct name { \
283  struct type *first; \
284  struct type *last; \
285  ast_mutex_t lock; \
286 } name = AST_DLLIST_HEAD_INIT_VALUE
287 #endif
288 
289 /*!
290  \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
291  \param name This will be the name of the defined structure.
292  \param type This is the type of each list entry.
293 
294  This macro creates a structure definition that can be used
295  to hold a list of the entries of type \a type, and allocates an instance
296  of it, initialized to be empty.
297 
298  Example usage:
299  \code
300  static AST_RWDLLIST_HEAD_STATIC(entry_list, entry);
301  \endcode
302 
303  This would define \c struct \c entry_list, intended to hold a list of
304  type \c struct \c entry.
305  \since 1.6.1
306 */
307 #ifndef AST_RWLOCK_INIT_VALUE
308 #define AST_RWDLLIST_HEAD_STATIC(name, type) \
309 struct name { \
310  struct type *first; \
311  struct type *last; \
312  ast_rwlock_t lock; \
313 } name; \
314 static void __attribute__((constructor)) __init_##name(void) \
315 { \
316  AST_RWDLLIST_HEAD_INIT(&name); \
317 } \
318 static void __attribute__((destructor)) __fini_##name(void) \
319 { \
320  AST_RWDLLIST_HEAD_DESTROY(&name); \
321 } \
322 struct __dummy_##name
323 #else
324 #define AST_RWDLLIST_HEAD_STATIC(name, type) \
325 struct name { \
326  struct type *first; \
327  struct type *last; \
328  ast_rwlock_t lock; \
329 } name = AST_RWDLLIST_HEAD_INIT_VALUE
330 #endif
331 
332 /*!
333  \brief Defines a structure to be used to hold a list of specified type, statically initialized.
334 
335  This is the same as AST_DLLIST_HEAD_STATIC, except without the lock included.
336  \since 1.6.1
337 */
338 #define AST_DLLIST_HEAD_NOLOCK_STATIC(name, type) \
339 struct name { \
340  struct type *first; \
341  struct type *last; \
342 } name = AST_DLLIST_HEAD_NOLOCK_INIT_VALUE
343 
344 /*!
345  \brief Initializes a list head structure with a specified first entry.
346  \param head This is a pointer to the list head structure
347  \param entry pointer to the list entry that will become the head of the list
348 
349  This macro initializes a list head structure by setting the head
350  entry to the supplied value and recreating the embedded lock.
351  \since 1.6.1
352 */
353 #define AST_DLLIST_HEAD_SET(head, entry) do { \
354  (head)->first = (entry); \
355  (head)->last = (entry); \
356  ast_mutex_init(&(head)->lock); \
357 } while (0)
358 
359 /*!
360  \brief Initializes an rwlist head structure with a specified first entry.
361  \param head This is a pointer to the list head structure
362  \param entry pointer to the list entry that will become the head of the list
363 
364  This macro initializes a list head structure by setting the head
365  entry to the supplied value and recreating the embedded lock.
366  \since 1.6.1
367 */
368 #define AST_RWDLLIST_HEAD_SET(head, entry) do { \
369  (head)->first = (entry); \
370  (head)->last = (entry); \
371  ast_rwlock_init(&(head)->lock); \
372 } while (0)
373 
374 /*!
375  \brief Initializes a list head structure with a specified first entry.
376  \param head This is a pointer to the list head structure
377  \param entry pointer to the list entry that will become the head of the list
378 
379  This macro initializes a list head structure by setting the head
380  entry to the supplied value.
381  \since 1.6.1
382 */
383 #define AST_DLLIST_HEAD_SET_NOLOCK(head, entry) do { \
384  (head)->first = (entry); \
385  (head)->last = (entry); \
386 } while (0)
387 
388 /*!
389  \brief Declare previous/forward links inside a list entry.
390  \param type This is the type of each list entry.
391 
392  This macro declares a structure to be used to doubly link list entries together.
393  It must be used inside the definition of the structure named in
394  \a type, as follows:
395 
396  \code
397  struct list_entry {
398  ...
399  AST_DLLIST_ENTRY(list_entry) list;
400  }
401  \endcode
402 
403  The field name \a list here is arbitrary, and can be anything you wish.
404  \since 1.6.1
405 */
406 #define AST_DLLIST_ENTRY(type) \
407 struct { \
408  struct type *prev; \
409  struct type *next; \
410 }
411 
412 #define AST_RWDLLIST_ENTRY AST_DLLIST_ENTRY
413 
414 /*!
415  \brief Returns the first entry contained in a list.
416  \param head This is a pointer to the list head structure
417  \since 1.6.1
418  */
419 #define AST_DLLIST_FIRST(head) ((head)->first)
420 
421 #define AST_RWDLLIST_FIRST AST_DLLIST_FIRST
422 
423 /*!
424  \brief Returns the last entry contained in a list.
425  \param head This is a pointer to the list head structure
426  \since 1.6.1
427  */
428 #define AST_DLLIST_LAST(head) ((head)->last)
429 
430 #define AST_RWDLLIST_LAST AST_DLLIST_LAST
431 
432 /*!
433  \brief Returns the next entry in the list after the given entry.
434  \param elm This is a pointer to the current entry.
435  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
436  used to link entries of this list together.
437  \since 1.6.1
438 */
439 #define AST_DLLIST_NEXT(elm, field) ((elm)->field.next)
440 
441 #define AST_RWDLLIST_NEXT AST_DLLIST_NEXT
442 
443 /*!
444  \brief Returns the previous entry in the list before the given entry.
445  \param elm This is a pointer to the current entry.
446  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
447  used to link entries of this list together.
448  \since 1.6.1
449 */
450 #define AST_DLLIST_PREV(elm, field) ((elm)->field.prev)
451 
452 #define AST_RWDLLIST_PREV AST_DLLIST_PREV
453 
454 /*!
455  \brief Checks whether the specified list contains any entries.
456  \param head This is a pointer to the list head structure
457 
458  \return non-zero if the list has entries
459  \return zero if not.
460  \since 1.6.1
461  */
462 #define AST_DLLIST_EMPTY(head) (AST_DLLIST_FIRST(head) == NULL)
463 
464 #define AST_RWDLLIST_EMPTY AST_DLLIST_EMPTY
465 
466 /*!
467  \brief Loops over (traverses) the entries in a list.
468  \param head This is a pointer to the list head structure
469  \param var This is the name of the variable that will hold a pointer to the
470  current list entry on each iteration. It must be declared before calling
471  this macro.
472  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
473  used to link entries of this list together.
474 
475  This macro is use to loop over (traverse) the entries in a list. It uses a
476  \a for loop, and supplies the enclosed code with a pointer to each list
477  entry as it loops. It is typically used as follows:
478  \code
479  static AST_DLLIST_HEAD(entry_list, list_entry) entries;
480  ...
481  struct list_entry {
482  ...
483  AST_DLLIST_ENTRY(list_entry) list;
484  }
485  ...
486  struct list_entry *current;
487  ...
488  AST_DLLIST_TRAVERSE(&entries, current, list) {
489  (do something with current here)
490  }
491  \endcode
492  \warning If you modify the forward-link pointer contained in the \a current entry while
493  inside the loop, the behavior will be unpredictable. At a minimum, the following
494  macros will modify the forward-link pointer, and should not be used inside
495  AST_DLLIST_TRAVERSE() against the entry pointed to by the \a current pointer without
496  careful consideration of their consequences:
497  \li AST_DLLIST_NEXT() (when used as an lvalue)
498  \li AST_DLLIST_INSERT_AFTER()
499  \li AST_DLLIST_INSERT_HEAD()
500  \li AST_DLLIST_INSERT_TAIL()
501  \since 1.6.1
502 */
503 #define AST_DLLIST_TRAVERSE(head,var,field) \
504  for((var) = (head)->first; (var); (var) = (var)->field.next)
505 
506 #define AST_RWDLLIST_TRAVERSE AST_DLLIST_TRAVERSE
507 
508 /*!
509  \brief Loops over (traverses) the entries in a list in reverse order, starting at the end.
510  \param head This is a pointer to the list head structure
511  \param var This is the name of the variable that will hold a pointer to the
512  current list entry on each iteration. It must be declared before calling
513  this macro.
514  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
515  used to link entries of this list together.
516 
517  This macro is use to loop over (traverse) the entries in a list in reverse order. It uses a
518  \a for loop, and supplies the enclosed code with a pointer to each list
519  entry as it loops. It is typically used as follows:
520  \code
521  static AST_DLLIST_HEAD(entry_list, list_entry) entries;
522  ...
523  struct list_entry {
524  ...
525  AST_DLLIST_ENTRY(list_entry) list;
526  }
527  ...
528  struct list_entry *current;
529  ...
530  AST_DLLIST_TRAVERSE_BACKWARDS(&entries, current, list) {
531  (do something with current here)
532  }
533  \endcode
534  \warning If you modify the forward-link pointer contained in the \a current entry while
535  inside the loop, the behavior will be unpredictable. At a minimum, the following
536  macros will modify the forward-link pointer, and should not be used inside
537  AST_DLLIST_TRAVERSE() against the entry pointed to by the \a current pointer without
538  careful consideration of their consequences:
539  \li AST_DLLIST_PREV() (when used as an lvalue)
540  \li AST_DLLIST_INSERT_BEFORE()
541  \li AST_DLLIST_INSERT_HEAD()
542  \li AST_DLLIST_INSERT_TAIL()
543  \since 1.6.1
544 */
545 #define AST_DLLIST_TRAVERSE_BACKWARDS(head,var,field) \
546  for((var) = (head)->last; (var); (var) = (var)->field.prev)
547 
548 #define AST_RWDLLIST_TRAVERSE_BACKWARDS AST_DLLIST_TRAVERSE_BACKWARDS
549 
550 /*!
551  \brief Loops safely over (traverses) the entries in a list.
552  \param head This is a pointer to the list head structure
553  \param var This is the name of the variable that will hold a pointer to the
554  current list entry on each iteration. It must be declared before calling
555  this macro.
556  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
557  used to link entries of this list together.
558 
559  This macro is used to safely loop over (traverse) the entries in a list. It
560  uses a \a for loop, and supplies the enclosed code with a pointer to each list
561  entry as it loops. It is typically used as follows:
562 
563  \code
564  static AST_DLLIST_HEAD(entry_list, list_entry) entries;
565  ...
566  struct list_entry {
567  ...
568  AST_DLLIST_ENTRY(list_entry) list;
569  }
570  ...
571  struct list_entry *current;
572  ...
573  AST_DLLIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
574  (do something with current here)
575  }
576  AST_DLLIST_TRAVERSE_SAFE_END;
577  \endcode
578 
579  It differs from AST_DLLIST_TRAVERSE() in that the code inside the loop can modify
580  (or even free, after calling AST_DLLIST_REMOVE_CURRENT()) the entry pointed to by
581  the \a current pointer without affecting the loop traversal.
582  \since 1.6.1
583 */
584 #define AST_DLLIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
585  typeof((head)) __list_head = head; \
586  typeof(__list_head->first) __list_next; \
587  typeof(__list_head->first) __list_prev = NULL; \
588  typeof(__list_head->first) __new_prev = NULL; \
589  for ((var) = __list_head->first, __new_prev = (var), \
590  __list_next = (var) ? (var)->field.next : NULL; \
591  (var); \
592  __list_prev = __new_prev, (var) = __list_next, \
593  __new_prev = (var), \
594  __list_next = (var) ? (var)->field.next : NULL \
595  )
596 
597 #define AST_RWDLLIST_TRAVERSE_SAFE_BEGIN AST_DLLIST_TRAVERSE_SAFE_BEGIN
598 
599 /*!
600  \brief Loops safely over (traverses) the entries in a list.
601  \param head This is a pointer to the list head structure
602  \param var This is the name of the variable that will hold a pointer to the
603  current list entry on each iteration. It must be declared before calling
604  this macro.
605  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
606  used to link entries of this list together.
607 
608  This macro is used to safely loop over (traverse) the entries in a list. It
609  uses a \a for loop, and supplies the enclosed code with a pointer to each list
610  entry as it loops. It is typically used as follows:
611 
612  \code
613  static AST_DLLIST_HEAD(entry_list, list_entry) entries;
614  ...
615  struct list_entry {
616  ...
617  AST_DLLIST_ENTRY(list_entry) list;
618  }
619  ...
620  struct list_entry *current;
621  ...
622  AST_DLLIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
623  (do something with current here)
624  }
625  AST_DLLIST_TRAVERSE_SAFE_END;
626  \endcode
627 
628  It differs from AST_DLLIST_TRAVERSE() in that the code inside the loop can modify
629  (or even free, after calling AST_DLLIST_REMOVE_CURRENT()) the entry pointed to by
630  the \a current pointer without affecting the loop traversal.
631  \since 1.6.1
632 */
633 #define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(head, var, field) { \
634  typeof((head)) __list_head = head; \
635  typeof(__list_head->first) __list_next; \
636  typeof(__list_head->first) __list_prev = NULL; \
637  typeof(__list_head->first) __new_prev = NULL; \
638  for ((var) = __list_head->last, __new_prev = (var), \
639  __list_next = NULL, __list_prev = (var) ? (var)->field.prev : NULL; \
640  (var); \
641  __list_next = __new_prev, (var) = __list_prev, \
642  __new_prev = (var), \
643  __list_prev = (var) ? (var)->field.prev : NULL \
644  )
645 
646 #define AST_RWDLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN
647 
648 /*!
649  \brief Removes the \a current entry from a list during a traversal.
650  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
651  used to link entries of this list together.
652 
653  \note This macro can \b only be used inside an AST_DLLIST_TRAVERSE_SAFE_BEGIN()
654  block; it is used to unlink the current entry from the list without affecting
655  the list traversal (and without having to re-traverse the list to modify the
656  previous entry, if any).
657  \since 1.6.1
658  */
659 #define AST_DLLIST_REMOVE_CURRENT(field) do { \
660  __new_prev->field.next = NULL; \
661  __new_prev->field.prev = NULL; \
662  if (__list_next) \
663  __new_prev = __list_prev; \
664  else \
665  __new_prev = NULL; \
666  if (__list_prev) { \
667  if (__list_next) \
668  __list_next->field.prev = __list_prev; \
669  __list_prev->field.next = __list_next; \
670  } else { \
671  __list_head->first = __list_next; \
672  if (__list_next) \
673  __list_next->field.prev = NULL; \
674  } \
675  if (!__list_next) \
676  __list_head->last = __list_prev; \
677  } while (0)
678 
679 #define AST_RWDLLIST_REMOVE_CURRENT AST_DLLIST_REMOVE_CURRENT
680 
681 #define AST_DLLIST_MOVE_CURRENT(newhead, field) do { \
682  typeof ((newhead)->first) __list_cur = __new_prev; \
683  AST_DLLIST_REMOVE_CURRENT(field); \
684  AST_DLLIST_INSERT_TAIL((newhead), __list_cur, field); \
685  } while (0)
686 
687 #define AST_RWDLLIST_MOVE_CURRENT AST_DLLIST_MOVE_CURRENT
688 
689 #define AST_DLLIST_MOVE_CURRENT_BACKWARDS(newhead, field) do { \
690  typeof ((newhead)->first) __list_cur = __new_prev; \
691  if (!__list_next) { \
692  AST_DLLIST_REMOVE_CURRENT(field); \
693  __new_prev = NULL; \
694  AST_DLLIST_INSERT_HEAD((newhead), __list_cur, field); \
695  } else { \
696  AST_DLLIST_REMOVE_CURRENT(field); \
697  AST_DLLIST_INSERT_HEAD((newhead), __list_cur, field); \
698  }} while (0)
699 
700 #define AST_RWDLLIST_MOVE_CURRENT_BACKWARDS AST_DLLIST_MOVE_CURRENT
701 
702 /*!
703  \brief Inserts a list entry before the current entry during a traversal.
704  \param elm This is a pointer to the entry to be inserted.
705  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
706  used to link entries of this list together.
707 
708  \note This macro can \b only be used inside an AST_DLLIST_TRAVERSE_SAFE_BEGIN()
709  block.
710  \since 1.6.1
711  */
712 #define AST_DLLIST_INSERT_BEFORE_CURRENT(elm, field) do { \
713  if (__list_prev) { \
714  (elm)->field.next = __list_prev->field.next; \
715  (elm)->field.prev = __list_prev; \
716  if (__list_prev->field.next) \
717  __list_prev->field.next->field.prev = (elm); \
718  __list_prev->field.next = (elm); \
719  } else { \
720  (elm)->field.next = __list_head->first; \
721  __list_head->first->field.prev = (elm); \
722  (elm)->field.prev = NULL; \
723  __list_head->first = (elm); \
724  } \
725 } while (0)
726 
727 #define AST_RWDLLIST_INSERT_BEFORE_CURRENT AST_DLLIST_INSERT_BEFORE_CURRENT
728 
729 /*!
730  \brief Inserts a list entry after the current entry during a backwards traversal. Since
731  this is a backwards traversal, this will insert the entry AFTER the current
732  element. Since this is a backwards traveral, though, this would be BEFORE
733  the current entry in traversal order. Confusing?
734  \param elm This is a pointer to the entry to be inserted.
735  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
736  used to link entries of this list together.
737 
738  \note This macro can \b only be used inside an AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN()
739  block. If you use this with the AST_DLLIST_TRAVERSE_SAFE_BEGIN(), be prepared for
740  strange things!
741  \since 1.6.1
742  */
743 #define AST_DLLIST_INSERT_BEFORE_CURRENT_BACKWARDS(elm, field) do { \
744  if (__list_next) { \
745  (elm)->field.next = __list_next; \
746  (elm)->field.prev = __new_prev; \
747  __new_prev->field.next = (elm); \
748  __list_next->field.prev = (elm); \
749  } else { \
750  (elm)->field.prev = __list_head->last; \
751  (elm)->field.next = NULL; \
752  __list_head->last->field.next = (elm); \
753  __list_head->last = (elm); \
754  } \
755 } while (0)
756 
757 #define AST_RWDLLIST_INSERT_BEFORE_CURRENT_BACKWARDS AST_DLLIST_INSERT_BEFORE_CURRENT_BACKWARDS
758 
759 /*!
760  \brief Closes a safe loop traversal block.
761  \since 1.6.1
762  */
763 #define AST_DLLIST_TRAVERSE_SAFE_END }
764 
765 #define AST_RWDLLIST_TRAVERSE_SAFE_END AST_DLLIST_TRAVERSE_SAFE_END
766 
767 /*!
768  \brief Closes a safe loop traversal block.
769  \since 1.6.1
770  */
771 #define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END }
772 
773 #define AST_RWDLLIST_TRAVERSE_BACKWARDS_SAFE_END AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END
774 
775 /*!
776  \brief Initializes a list head structure.
777  \param head This is a pointer to the list head structure
778 
779  This macro initializes a list head structure by setting the head
780  entry to \a NULL (empty list) and recreating the embedded lock.
781  \since 1.6.1
782 */
783 #define AST_DLLIST_HEAD_INIT(head) { \
784  (head)->first = NULL; \
785  (head)->last = NULL; \
786  ast_mutex_init(&(head)->lock); \
787 }
788 
789 /*!
790  \brief Initializes an rwlist head structure.
791  \param head This is a pointer to the list head structure
792 
793  This macro initializes a list head structure by setting the head
794  entry to \a NULL (empty list) and recreating the embedded lock.
795  \since 1.6.1
796 */
797 #define AST_RWDLLIST_HEAD_INIT(head) { \
798  (head)->first = NULL; \
799  (head)->last = NULL; \
800  ast_rwlock_init(&(head)->lock); \
801 }
802 
803 /*!
804  \brief Destroys a list head structure.
805  \param head This is a pointer to the list head structure
806 
807  This macro destroys a list head structure by setting the head
808  entry to \a NULL (empty list) and destroying the embedded lock.
809  It does not free the structure from memory.
810  \since 1.6.1
811 */
812 #define AST_DLLIST_HEAD_DESTROY(head) { \
813  (head)->first = NULL; \
814  (head)->last = NULL; \
815  ast_mutex_destroy(&(head)->lock); \
816 }
817 
818 /*!
819  \brief Destroys an rwlist head structure.
820  \param head This is a pointer to the list head structure
821 
822  This macro destroys a list head structure by setting the head
823  entry to \a NULL (empty list) and destroying the embedded lock.
824  It does not free the structure from memory.
825  \since 1.6.1
826 */
827 #define AST_RWDLLIST_HEAD_DESTROY(head) { \
828  (head)->first = NULL; \
829  (head)->last = NULL; \
830  ast_rwlock_destroy(&(head)->lock); \
831 }
832 
833 /*!
834  \brief Initializes a list head structure.
835  \param head This is a pointer to the list head structure
836 
837  This macro initializes a list head structure by setting the head
838  entry to \a NULL (empty list). There is no embedded lock handling
839  with this macro.
840  \since 1.6.1
841 */
842 #define AST_DLLIST_HEAD_INIT_NOLOCK(head) { \
843  (head)->first = NULL; \
844  (head)->last = NULL; \
845 }
846 
847 /*!
848  \brief Inserts a list entry after a given entry.
849  \param head This is a pointer to the list head structure
850  \param listelm This is a pointer to the entry after which the new entry should
851  be inserted.
852  \param elm This is a pointer to the entry to be inserted.
853  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
854  used to link entries of this list together.
855  \since 1.6.1
856  */
857 #define AST_DLLIST_INSERT_AFTER(head, listelm, elm, field) do { \
858  (elm)->field.next = (listelm)->field.next; \
859  (elm)->field.prev = (listelm); \
860  if ((listelm)->field.next) \
861  (listelm)->field.next->field.prev = (elm); \
862  (listelm)->field.next = (elm); \
863  if ((head)->last == (listelm)) \
864  (head)->last = (elm); \
865 } while (0)
866 
867 #define AST_RWDLLIST_INSERT_AFTER AST_DLLIST_INSERT_AFTER
868 
869 /*!
870  \brief Inserts a list entry before a given entry.
871  \param head This is a pointer to the list head structure
872  \param listelm This is a pointer to the entry before which the new entry should
873  be inserted.
874  \param elm This is a pointer to the entry to be inserted.
875  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
876  used to link entries of this list together.
877  \since 1.6.1
878  */
879 #define AST_DLLIST_INSERT_BEFORE(head, listelm, elm, field) do { \
880  (elm)->field.next = (listelm); \
881  (elm)->field.prev = (listelm)->field.prev; \
882  if ((listelm)->field.prev) \
883  (listelm)->field.prev->field.next = (elm); \
884  (listelm)->field.prev = (elm); \
885  if ((head)->first == (listelm)) \
886  (head)->first = (elm); \
887 } while (0)
888 
889 #define AST_RWDLLIST_INSERT_BEFORE AST_DLLIST_INSERT_BEFORE
890 
891 /*!
892  \brief Inserts a list entry at the head of a list.
893  \param head This is a pointer to the list head structure
894  \param elm This is a pointer to the entry to be inserted.
895  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
896  used to link entries of this list together.
897  \since 1.6.1
898  */
899 #define AST_DLLIST_INSERT_HEAD(head, elm, field) do { \
900  (elm)->field.next = (head)->first; \
901  if ((head)->first) \
902  (head)->first->field.prev = (elm); \
903  (elm)->field.prev = NULL; \
904  (head)->first = (elm); \
905  if (!(head)->last) \
906  (head)->last = (elm); \
907 } while (0)
908 
909 #define AST_RWDLLIST_INSERT_HEAD AST_DLLIST_INSERT_HEAD
910 
911 /*!
912  \brief Appends a list entry to the tail of a list.
913  \param head This is a pointer to the list head structure
914  \param elm This is a pointer to the entry to be appended.
915  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
916  used to link entries of this list together.
917 
918  Note: The link field in the appended entry is \b not modified, so if it is
919  actually the head of a list itself, the entire list will be appended
920  temporarily (until the next AST_DLLIST_INSERT_TAIL is performed).
921  \since 1.6.1
922  */
923 #define AST_DLLIST_INSERT_TAIL(head, elm, field) do { \
924  if (!(head)->first) { \
925  (head)->first = (elm); \
926  (head)->last = (elm); \
927  (elm)->field.next = NULL; \
928  (elm)->field.prev = NULL; \
929  } else { \
930  (head)->last->field.next = (elm); \
931  (elm)->field.prev = (head)->last; \
932  (elm)->field.next = NULL; \
933  (head)->last = (elm); \
934  } \
935 } while (0)
936 
937 #define AST_RWDLLIST_INSERT_TAIL AST_DLLIST_INSERT_TAIL
938 
939 /*!
940  \brief Appends a whole list to the tail of a list.
941  \param head This is a pointer to the list head structure
942  \param list This is a pointer to the list to be appended.
943  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
944  used to link entries of this list together.
945 
946  Note: The source list (the \a list parameter) will be empty after
947  calling this macro (the list entries are \b moved to the target list).
948  \since 1.6.1
949  */
950 #define AST_DLLIST_APPEND_DLLIST(head, list, field) do { \
951  if (!(head)->first) { \
952  (head)->first = (list)->first; \
953  (head)->last = (list)->last; \
954  } else { \
955  (head)->last->field.next = (list)->first; \
956  (list)->first->field.prev = (head)->last; \
957  (head)->last = (list)->last; \
958  } \
959  (list)->first = NULL; \
960  (list)->last = NULL; \
961 } while (0)
962 
963 #define AST_RWDLLIST_APPEND_DLLIST AST_DLLIST_APPEND_DLLIST
964 
965 /*!
966  \brief Removes and returns the head entry from a list.
967  \param head This is a pointer to the list head structure
968  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
969  used to link entries of this list together.
970 
971  Removes the head entry from the list, and returns a pointer to it.
972  This macro is safe to call on an empty list.
973  \since 1.6.1
974  */
975 #define AST_DLLIST_REMOVE_HEAD(head, field) ({ \
976  typeof((head)->first) cur = (head)->first; \
977  if (cur) { \
978  (head)->first = cur->field.next; \
979  if (cur->field.next) \
980  cur->field.next->field.prev = NULL; \
981  cur->field.next = NULL; \
982  if ((head)->last == cur) \
983  (head)->last = NULL; \
984  } \
985  cur; \
986  })
987 
988 #define AST_RWDLLIST_REMOVE_HEAD AST_DLLIST_REMOVE_HEAD
989 
990 /*!
991  \brief Removes a specific entry from a list.
992  \param head This is a pointer to the list head structure
993  \param elm This is a pointer to the entry to be removed.
994  \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
995  used to link entries of this list together.
996  \warning The removed entry is \b not freed nor modified in any way.
997  \since 1.6.1
998  */
999 #define AST_DLLIST_REMOVE(head, elm, field) ({ \
1000  __typeof(elm) __res = (elm); \
1001  if ((head)->first == (elm)) { \
1002  (head)->first = (elm)->field.next; \
1003  if ((elm)->field.next) \
1004  (elm)->field.next->field.prev = NULL; \
1005  if ((head)->last == (elm)) \
1006  (head)->last = NULL; \
1007  } else { \
1008  (elm)->field.prev->field.next = (elm)->field.next; \
1009  if ((elm)->field.next) \
1010  (elm)->field.next->field.prev = (elm)->field.prev; \
1011  if ((head)->last == (elm)) \
1012  (head)->last = (elm)->field.prev; \
1013  } \
1014  (elm)->field.next = NULL; \
1015  (elm)->field.prev = NULL; \
1016  (__res); \
1017 })
1018 
1019 #define AST_RWDLLIST_REMOVE AST_DLLIST_REMOVE
1020 
1021 #endif /* _ASTERISK_DLINKEDLISTS_H */
Asterisk locking-related definitions: