Asterisk - The Open Source Telephony Project
GIT-master-f36a736
include
asterisk
linkedlists.h
Go to the documentation of this file.
1
/*
2
* Asterisk -- An open source telephony toolkit.
3
*
4
* Copyright (C) 1999 - 2006, Digium, Inc.
5
*
6
* Mark Spencer <markster@digium.com>
7
* Kevin P. Fleming <kpfleming@digium.com>
8
*
9
* See http://www.asterisk.org for more information about
10
* the Asterisk project. Please do not directly contact
11
* any of the maintainers of this project for assistance;
12
* the project provides a web site, mailing lists and IRC
13
* channels for your use.
14
*
15
* This program is free software, distributed under the terms of
16
* the GNU General Public License Version 2. See the LICENSE file
17
* at the top of the source tree.
18
*/
19
20
#ifndef ASTERISK_LINKEDLISTS_H
21
#define ASTERISK_LINKEDLISTS_H
22
23
#include "
asterisk/lock.h
"
24
25
/*!
26
* \file
27
*
28
* \brief A set of macros to manage forward-linked lists.
29
*/
30
31
/*!
32
* \brief Locks a list.
33
* \param head This is a pointer to the list head structure
34
*
35
* This macro attempts to place an exclusive lock in the
36
* list head structure pointed to by head.
37
* \retval 0 on success
38
* \retval non-zero on failure
39
*/
40
#define AST_LIST_LOCK(head) \
41
ast_mutex_lock(&(head)->lock)
42
43
/*!
44
* \brief Write locks a list.
45
* \param head This is a pointer to the list head structure
46
*
47
* This macro attempts to place an exclusive write lock in the
48
* list head structure pointed to by head.
49
* \retval 0 on success
50
* \retval non-zero on failure
51
*/
52
#define AST_RWLIST_WRLOCK(head) \
53
ast_rwlock_wrlock(&(head)->lock)
54
55
/*!
56
* \brief Write locks a list, with timeout.
57
* \param head This is a pointer to the list head structure
58
* \param ts Pointer to a timespec structure
59
*
60
* This macro attempts to place an exclusive write lock in the
61
* list head structure pointed to by head.
62
* \retval 0 on success
63
* \retval non-zero on failure
64
*
65
* \since 1.6.1
66
*/
67
#define AST_RWLIST_TIMEDWRLOCK(head, ts) ast_rwlock_timedwrlock(&(head)->lock, ts)
68
69
/*!
70
* \brief Read locks a list.
71
* \param head This is a pointer to the list head structure
72
*
73
* This macro attempts to place a read lock in the
74
* list head structure pointed to by head.
75
* \retval 0 on success
76
* \retval non-zero on failure
77
*/
78
#define AST_RWLIST_RDLOCK(head) \
79
ast_rwlock_rdlock(&(head)->lock)
80
81
/*!
82
* \brief Read locks a list, with timeout.
83
* \param head This is a pointer to the list head structure
84
* \param ts Pointer to a timespec structure
85
*
86
* This macro attempts to place a read lock in the
87
* list head structure pointed to by head.
88
* \retval 0 on success
89
* \retval non-zero on failure
90
*
91
* \since 1.6.1
92
*/
93
#define AST_RWLIST_TIMEDRDLOCK(head, ts) \
94
ast_rwlock_timedrdlock(&(head)->lock, ts)
95
96
/*!
97
* \brief Locks a list, without blocking if the list is locked.
98
* \param head This is a pointer to the list head structure
99
*
100
* This macro attempts to place an exclusive lock in the
101
* list head structure pointed to by head.
102
* \retval 0 on success
103
* \retval non-zero on failure
104
*/
105
#define AST_LIST_TRYLOCK(head) \
106
ast_mutex_trylock(&(head)->lock)
107
108
/*!
109
* \brief Write locks a list, without blocking if the list is locked.
110
* \param head This is a pointer to the list head structure
111
*
112
* This macro attempts to place an exclusive write lock in the
113
* list head structure pointed to by head.
114
* \retval 0 on success
115
* \retval non-zero on failure
116
*/
117
#define AST_RWLIST_TRYWRLOCK(head) \
118
ast_rwlock_trywrlock(&(head)->lock)
119
120
/*!
121
* \brief Read locks a list, without blocking if the list is locked.
122
* \param head This is a pointer to the list head structure
123
*
124
* This macro attempts to place a read lock in the
125
* list head structure pointed to by head.
126
* \retval 0 on success
127
* \retval non-zero on failure
128
*/
129
#define AST_RWLIST_TRYRDLOCK(head) \
130
ast_rwlock_tryrdlock(&(head)->lock)
131
132
/*!
133
* \brief Attempts to unlock a list.
134
* \param head This is a pointer to the list head structure
135
*
136
* This macro attempts to remove an exclusive lock from the
137
* list head structure pointed to by head. If the list
138
* was not locked by this thread, this macro has no effect.
139
*/
140
#define AST_LIST_UNLOCK(head) \
141
ast_mutex_unlock(&(head)->lock)
142
143
/*!
144
* \brief Attempts to unlock a read/write based list.
145
* \param head This is a pointer to the list head structure
146
*
147
* This macro attempts to remove a read or write lock from the
148
* list head structure pointed to by head. If the list
149
* was not locked by this thread, this macro has no effect.
150
*/
151
#define AST_RWLIST_UNLOCK(head) \
152
ast_rwlock_unlock(&(head)->lock)
153
154
/*!
155
* \brief Defines a structure to be used to hold a list of specified type.
156
* \param name This will be the name of the defined structure.
157
* \param type This is the type of each list entry.
158
*
159
* This macro creates a structure definition that can be used
160
* to hold a list of the entries of type \a type. It does not actually
161
* declare (allocate) a structure; to do that, either follow this
162
* macro with the desired name of the instance you wish to declare,
163
* or use the specified \a name to declare instances elsewhere.
164
*
165
* Example usage:
166
* \code
167
* static AST_LIST_HEAD(entry_list, entry) entries;
168
* \endcode
169
*
170
* This would define \c struct \c entry_list, and declare an instance of it named
171
* \a entries, all intended to hold a list of type \c struct \c entry.
172
*/
173
#define AST_LIST_HEAD(name, type) \
174
struct name { \
175
struct type *first; \
176
struct type *last; \
177
ast_mutex_t lock; \
178
}
179
180
/*!
181
* \brief Defines a structure to be used to hold a read/write list of specified type.
182
* \param name This will be the name of the defined structure.
183
* \param type This is the type of each list entry.
184
*
185
* This macro creates a structure definition that can be used
186
* to hold a list of the entries of type \a type. It does not actually
187
* declare (allocate) a structure; to do that, either follow this
188
* macro with the desired name of the instance you wish to declare,
189
* or use the specified \a name to declare instances elsewhere.
190
*
191
* Example usage:
192
* \code
193
* static AST_RWLIST_HEAD(entry_list, entry) entries;
194
* \endcode
195
*
196
* This would define \c struct \c entry_list, and declare an instance of it named
197
* \a entries, all intended to hold a list of type \c struct \c entry.
198
*/
199
#define AST_RWLIST_HEAD(name, type) \
200
struct name { \
201
struct type *first; \
202
struct type *last; \
203
ast_rwlock_t lock; \
204
}
205
206
/*!
207
* \brief Defines a structure to be used to hold a list of specified type (with no lock).
208
* \param name This will be the name of the defined structure.
209
* \param type This is the type of each list entry.
210
*
211
* This macro creates a structure definition that can be used
212
* to hold a list of the entries of type \a type. It does not actually
213
* declare (allocate) a structure; to do that, either follow this
214
* macro with the desired name of the instance you wish to declare,
215
* or use the specified \a name to declare instances elsewhere.
216
*
217
* Example usage:
218
* \code
219
* static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
220
* \endcode
221
*
222
* This would define \c struct \c entry_list, and declare an instance of it named
223
* \a entries, all intended to hold a list of type \c struct \c entry.
224
*/
225
#define AST_LIST_HEAD_NOLOCK(name, type) \
226
struct name { \
227
struct type *first; \
228
struct type *last; \
229
}
230
231
/*!
232
* \brief Defines initial values for a declaration of AST_LIST_HEAD
233
*/
234
#define AST_LIST_HEAD_INIT_VALUE { \
235
.first = NULL, \
236
.last = NULL, \
237
.lock = AST_MUTEX_INIT_VALUE, \
238
}
239
240
/*!
241
* \brief Defines initial values for a declaration of AST_RWLIST_HEAD
242
*/
243
#define AST_RWLIST_HEAD_INIT_VALUE { \
244
.first = NULL, \
245
.last = NULL, \
246
.lock = AST_RWLOCK_INIT_VALUE, \
247
}
248
249
/*!
250
* \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
251
*/
252
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
253
.first = NULL, \
254
.last = NULL, \
255
}
256
257
/*!
258
* \brief Defines a structure to be used to hold a list of specified type, statically initialized.
259
* \param name This will be the name of the defined structure.
260
* \param type This is the type of each list entry.
261
*
262
* This macro creates a structure definition that can be used
263
* to hold a list of the entries of type \a type, and allocates an instance
264
* of it, initialized to be empty.
265
*
266
* Example usage:
267
* \code
268
* static AST_LIST_HEAD_STATIC(entry_list, entry);
269
* \endcode
270
*
271
* This would define \c struct \c entry_list, intended to hold a list of
272
* type \c struct \c entry.
273
*/
274
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
275
#define AST_LIST_HEAD_STATIC(name, type) \
276
struct name { \
277
struct type *first; \
278
struct type *last; \
279
ast_mutex_t lock; \
280
} name; \
281
static void __attribute__((constructor)) __init_##name(void) \
282
{ \
283
AST_LIST_HEAD_INIT(&name); \
284
} \
285
static void __attribute__((destructor)) __fini_##name(void) \
286
{ \
287
AST_LIST_HEAD_DESTROY(&name); \
288
} \
289
struct __dummy_##name
290
#else
291
#define AST_LIST_HEAD_STATIC(name, type) \
292
struct name { \
293
struct type *first; \
294
struct type *last; \
295
ast_mutex_t lock; \
296
} name = AST_LIST_HEAD_INIT_VALUE
297
#endif
298
299
/*!
300
* \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
301
* \param name This will be the name of the defined structure.
302
* \param type This is the type of each list entry.
303
*
304
* This macro creates a structure definition that can be used
305
* to hold a list of the entries of type \a type, and allocates an instance
306
* of it, initialized to be empty.
307
*
308
* Example usage:
309
* \code
310
* static AST_RWLIST_HEAD_STATIC(entry_list, entry);
311
* \endcode
312
*
313
* This would define \c struct \c entry_list, intended to hold a list of
314
* type \c struct \c entry.
315
*/
316
#ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
317
#define AST_RWLIST_HEAD_STATIC(name, type) \
318
struct name { \
319
struct type *first; \
320
struct type *last; \
321
ast_rwlock_t lock; \
322
} name; \
323
static void __attribute__((constructor)) __init_##name(void) \
324
{ \
325
AST_RWLIST_HEAD_INIT(&name); \
326
} \
327
static void __attribute__((destructor)) __fini_##name(void) \
328
{ \
329
AST_RWLIST_HEAD_DESTROY(&name); \
330
} \
331
struct __dummy_##name
332
#else
333
#define AST_RWLIST_HEAD_STATIC(name, type) \
334
struct name { \
335
struct type *first; \
336
struct type *last; \
337
ast_rwlock_t lock; \
338
} name = AST_RWLIST_HEAD_INIT_VALUE
339
#endif
340
341
/*!
342
* \brief Defines a structure to be used to hold a list of specified type, statically initialized.
343
*
344
* This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
345
*/
346
#define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
347
struct name { \
348
struct type *first; \
349
struct type *last; \
350
} name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
351
352
/*!
353
* \brief Initializes a list head structure with a specified first entry.
354
* \param head This is a pointer to the list head structure
355
* \param entry pointer to the list entry that will become the head of the list
356
*
357
* This macro initializes a list head structure by setting the head
358
* entry to the supplied value and recreating the embedded lock.
359
*/
360
#define AST_LIST_HEAD_SET(head, entry) do { \
361
(head)->first = (entry); \
362
(head)->last = (entry); \
363
ast_mutex_init(&(head)->lock); \
364
} while (0)
365
366
/*!
367
* \brief Initializes an rwlist head structure with a specified first entry.
368
* \param head This is a pointer to the list head structure
369
* \param entry pointer to the list entry that will become the head of the list
370
*
371
* This macro initializes a list head structure by setting the head
372
* entry to the supplied value and recreating the embedded lock.
373
*/
374
#define AST_RWLIST_HEAD_SET(head, entry) do { \
375
(head)->first = (entry); \
376
(head)->last = (entry); \
377
ast_rwlock_init(&(head)->lock); \
378
} while (0)
379
380
/*!
381
* \brief Initializes a list head structure with a specified first entry.
382
* \param head This is a pointer to the list head structure
383
* \param entry pointer to the list entry that will become the head of the list
384
*
385
* This macro initializes a list head structure by setting the head
386
* entry to the supplied value.
387
*/
388
#define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
389
(head)->first = (entry); \
390
(head)->last = (entry); \
391
} while (0)
392
393
/*!
394
* \brief Declare a forward link structure inside a list entry.
395
* \param type This is the type of each list entry.
396
*
397
* This macro declares a structure to be used to link list entries together.
398
* It must be used inside the definition of the structure named in
399
* \a type, as follows:
400
*
401
* \code
402
* struct list_entry {
403
...
404
AST_LIST_ENTRY(list_entry) list;
405
* }
406
* \endcode
407
*
408
* The field name \a list here is arbitrary, and can be anything you wish.
409
*/
410
#define AST_LIST_ENTRY(type) \
411
struct { \
412
struct type *next; \
413
}
414
415
#define AST_RWLIST_ENTRY AST_LIST_ENTRY
416
417
/*!
418
* \brief Returns the first entry contained in a list.
419
* \param head This is a pointer to the list head structure
420
*/
421
#define AST_LIST_FIRST(head) ((head)->first)
422
423
#define AST_RWLIST_FIRST AST_LIST_FIRST
424
425
/*!
426
* \brief Returns the last entry contained in a list.
427
* \param head This is a pointer to the list head structure
428
*/
429
#define AST_LIST_LAST(head) ((head)->last)
430
431
#define AST_RWLIST_LAST AST_LIST_LAST
432
433
/*!
434
* \brief Returns the next entry in the list after the given entry.
435
* \param elm This is a pointer to the current entry.
436
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
437
* used to link entries of this list together.
438
*/
439
#define AST_LIST_NEXT(elm, field) ((elm)->field.next)
440
441
#define AST_RWLIST_NEXT AST_LIST_NEXT
442
443
/*!
444
* \brief Checks whether the specified list contains any entries.
445
* \param head This is a pointer to the list head structure
446
*
447
* \return zero if the list has entries
448
* \return non-zero if not.
449
*/
450
#define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
451
452
#define AST_RWLIST_EMPTY AST_LIST_EMPTY
453
454
/*!
455
* \brief Loops over (traverses) the entries in a list.
456
* \param head This is a pointer to the list head structure
457
* \param var This is the name of the variable that will hold a pointer to the
458
* current list entry on each iteration. It must be declared before calling
459
* this macro.
460
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
461
* used to link entries of this list together.
462
*
463
* This macro is use to loop over (traverse) the entries in a list. It uses a
464
* \a for loop, and supplies the enclosed code with a pointer to each list
465
* entry as it loops. It is typically used as follows:
466
* \code
467
* static AST_LIST_HEAD(entry_list, list_entry) entries;
468
* ...
469
* struct list_entry {
470
...
471
AST_LIST_ENTRY(list_entry) list;
472
* }
473
* ...
474
* struct list_entry *current;
475
* ...
476
* AST_LIST_TRAVERSE(&entries, current, list) {
477
(do something with current here)
478
* }
479
* \endcode
480
* \warning If you modify the forward-link pointer contained in the \a current entry while
481
* inside the loop, the behavior will be unpredictable. At a minimum, the following
482
* macros will modify the forward-link pointer, and should not be used inside
483
* AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
484
* careful consideration of their consequences:
485
* \li AST_LIST_NEXT() (when used as an lvalue)
486
* \li AST_LIST_INSERT_AFTER()
487
* \li AST_LIST_INSERT_HEAD()
488
* \li AST_LIST_INSERT_TAIL()
489
* \li AST_LIST_INSERT_SORTALPHA()
490
*/
491
#define AST_LIST_TRAVERSE(head,var,field) \
492
for((var) = (head)->first; (var); (var) = (var)->field.next)
493
494
#define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
495
496
/*!
497
* \brief Loops safely over (traverses) the entries in a list.
498
* \param head This is a pointer to the list head structure
499
* \param var This is the name of the variable that will hold a pointer to the
500
* current list entry on each iteration. It must be declared before calling
501
* this macro.
502
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
503
* used to link entries of this list together.
504
*
505
* This macro is used to safely loop over (traverse) the entries in a list. It
506
* uses a \a for loop, and supplies the enclosed code with a pointer to each list
507
* entry as it loops. It is typically used as follows:
508
*
509
* \code
510
* static AST_LIST_HEAD(entry_list, list_entry) entries;
511
* ...
512
* struct list_entry {
513
...
514
AST_LIST_ENTRY(list_entry) list;
515
* }
516
* ...
517
* struct list_entry *current;
518
* ...
519
* AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
520
(do something with current here)
521
* }
522
* AST_LIST_TRAVERSE_SAFE_END;
523
* \endcode
524
*
525
* It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
526
* (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
527
* the \a current pointer without affecting the loop traversal.
528
*/
529
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
530
typeof((head)) __list_head = head; \
531
typeof(__list_head->first) __list_next; \
532
typeof(__list_head->first) __list_prev = NULL; \
533
typeof(__list_head->first) __list_current; \
534
for ((var) = __list_head->first, \
535
__list_current = (var), \
536
__list_next = (var) ? (var)->field.next : NULL; \
537
(var); \
538
__list_prev = __list_current, \
539
(var) = __list_next, \
540
__list_current = (var), \
541
__list_next = (var) ? (var)->field.next : NULL, \
542
(void) __list_prev
/* To quiet compiler? */
\
543
)
544
545
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
546
547
/*!
548
* \brief Removes the \a current entry from a list during a traversal.
549
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
550
* used to link entries of this list together.
551
*
552
* \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
553
* block; it is used to unlink the current entry from the list without affecting
554
* the list traversal (and without having to re-traverse the list to modify the
555
* previous entry, if any).
556
*/
557
#define AST_LIST_REMOVE_CURRENT(field) do { \
558
__list_current->field.next = NULL; \
559
__list_current = __list_prev; \
560
if (__list_prev) { \
561
__list_prev->field.next = __list_next; \
562
} else { \
563
__list_head->first = __list_next; \
564
} \
565
if (!__list_next) { \
566
__list_head->last = __list_prev; \
567
} \
568
} while (0)
569
570
#define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
571
572
/*!
573
* \brief Move the current list entry to another list.
574
*
575
* \note This is a silly macro. It should be done explicitly
576
* otherwise the field parameter must be the same for the two
577
* lists.
578
*
579
* AST_LIST_REMOVE_CURRENT(field);
580
* AST_LIST_INSERT_TAIL(newhead, var, other_field);
581
*/
582
#define AST_LIST_MOVE_CURRENT(newhead, field) do { \
583
typeof ((newhead)->first) __extracted = __list_current; \
584
AST_LIST_REMOVE_CURRENT(field); \
585
AST_LIST_INSERT_TAIL((newhead), __extracted, field); \
586
} while (0)
587
588
#define AST_RWLIST_MOVE_CURRENT AST_LIST_MOVE_CURRENT
589
590
/*!
591
* \brief Inserts a list entry before the current entry during a traversal.
592
* \param elm This is a pointer to the entry to be inserted.
593
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
594
* used to link entries of this list together.
595
*
596
* \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
597
* block.
598
*/
599
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field) do { \
600
if (__list_prev) { \
601
(elm)->field.next = __list_prev->field.next; \
602
__list_prev->field.next = elm; \
603
} else { \
604
(elm)->field.next = __list_head->first; \
605
__list_head->first = (elm); \
606
} \
607
__list_prev = (elm); \
608
} while (0)
609
610
#define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
611
612
/*!
613
* \brief Closes a safe loop traversal block.
614
*/
615
#define AST_LIST_TRAVERSE_SAFE_END }
616
617
#define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
618
619
/*!
620
* \brief Initializes a list head structure.
621
* \param head This is a pointer to the list head structure
622
*
623
* This macro initializes a list head structure by setting the head
624
* entry to \a NULL (empty list) and recreating the embedded lock.
625
*/
626
#define AST_LIST_HEAD_INIT(head) { \
627
(head)->first = NULL; \
628
(head)->last = NULL; \
629
ast_mutex_init(&(head)->lock); \
630
}
631
632
/*!
633
* \brief Initializes an rwlist head structure.
634
* \param head This is a pointer to the list head structure
635
*
636
* This macro initializes a list head structure by setting the head
637
* entry to \a NULL (empty list) and recreating the embedded lock.
638
*/
639
#define AST_RWLIST_HEAD_INIT(head) { \
640
(head)->first = NULL; \
641
(head)->last = NULL; \
642
ast_rwlock_init(&(head)->lock); \
643
}
644
645
/*!
646
* \brief Destroys a list head structure.
647
* \param head This is a pointer to the list head structure
648
*
649
* This macro destroys a list head structure by setting the head
650
* entry to \a NULL (empty list) and destroying the embedded lock.
651
* It does not free the structure from memory.
652
*/
653
#define AST_LIST_HEAD_DESTROY(head) { \
654
(head)->first = NULL; \
655
(head)->last = NULL; \
656
ast_mutex_destroy(&(head)->lock); \
657
}
658
659
/*!
660
* \brief Destroys an rwlist head structure.
661
* \param head This is a pointer to the list head structure
662
*
663
* This macro destroys a list head structure by setting the head
664
* entry to \a NULL (empty list) and destroying the embedded lock.
665
* It does not free the structure from memory.
666
*/
667
#define AST_RWLIST_HEAD_DESTROY(head) { \
668
(head)->first = NULL; \
669
(head)->last = NULL; \
670
ast_rwlock_destroy(&(head)->lock); \
671
}
672
673
/*!
674
* \brief Initializes a list head structure.
675
* \param head This is a pointer to the list head structure
676
*
677
* This macro initializes a list head structure by setting the head
678
* entry to \a NULL (empty list). There is no embedded lock handling
679
* with this macro.
680
*/
681
#define AST_LIST_HEAD_INIT_NOLOCK(head) { \
682
(head)->first = NULL; \
683
(head)->last = NULL; \
684
}
685
686
/*!
687
* \brief Inserts a list entry after a given entry.
688
* \param head This is a pointer to the list head structure
689
* \param listelm This is a pointer to the entry after which the new entry should
690
* be inserted.
691
* \param elm This is a pointer to the entry to be inserted.
692
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
693
* used to link entries of this list together.
694
*/
695
#define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
696
(elm)->field.next = (listelm)->field.next; \
697
(listelm)->field.next = (elm); \
698
if ((head)->last == (listelm)) \
699
(head)->last = (elm); \
700
} while (0)
701
702
#define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
703
704
/*!
705
* \brief Inserts a list entry at the head of a list.
706
* \param head This is a pointer to the list head structure
707
* \param elm This is a pointer to the entry to be inserted.
708
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
709
* used to link entries of this list together.
710
*/
711
#define AST_LIST_INSERT_HEAD(head, elm, field) do { \
712
(elm)->field.next = (head)->first; \
713
(head)->first = (elm); \
714
if (!(head)->last) \
715
(head)->last = (elm); \
716
} while (0)
717
718
#define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
719
720
/*!
721
* \brief Appends a list entry to the tail of a list.
722
* \param head This is a pointer to the list head structure
723
* \param elm This is a pointer to the entry to be appended.
724
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
725
* used to link entries of this list together.
726
*
727
* Note: The link field in the appended entry is \b not modified, so if it is
728
* actually the head of a list itself, the entire list will be appended
729
* temporarily (until the next AST_LIST_INSERT_TAIL is performed).
730
*/
731
#define AST_LIST_INSERT_TAIL(head, elm, field) do { \
732
if (!(head)->first) { \
733
(head)->first = (elm); \
734
(head)->last = (elm); \
735
} else { \
736
(head)->last->field.next = (elm); \
737
(head)->last = (elm); \
738
} \
739
} while (0)
740
741
#define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
742
743
/*!
744
* \brief Inserts a list entry into a alphabetically sorted list
745
* \param head Pointer to the list head structure
746
* \param elm Pointer to the entry to be inserted
747
* \param field Name of the list entry field (declared using AST_LIST_ENTRY())
748
* \param sortfield Name of the field on which the list is sorted
749
* \since 1.6.1
750
*/
751
#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield) do { \
752
if (!(head)->first) { \
753
(head)->first = (elm); \
754
(head)->last = (elm); \
755
} else { \
756
typeof((head)->first) __cur = (head)->first, __prev = NULL; \
757
while (__cur && strcmp(__cur->sortfield, elm->sortfield) < 0) { \
758
__prev = __cur; \
759
__cur = __cur->field.next; \
760
} \
761
if (!__prev) { \
762
AST_LIST_INSERT_HEAD(head, elm, field); \
763
} else if (!__cur) { \
764
AST_LIST_INSERT_TAIL(head, elm, field); \
765
} else { \
766
AST_LIST_INSERT_AFTER(head, __prev, elm, field); \
767
} \
768
} \
769
} while (0)
770
771
#define AST_RWLIST_INSERT_SORTALPHA AST_LIST_INSERT_SORTALPHA
772
773
/*!
774
* \brief Appends a whole list to the tail of a list.
775
* \param head This is a pointer to the list head structure
776
* \param list This is a pointer to the list to be appended.
777
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
778
* used to link entries of this list together.
779
*
780
* Note: The source list (the \a list parameter) will be empty after
781
* calling this macro (the list entries are \b moved to the target list).
782
*/
783
#define AST_LIST_APPEND_LIST(head, list, field) do { \
784
if (!(list)->first) { \
785
break; \
786
} \
787
if (!(head)->first) { \
788
(head)->first = (list)->first; \
789
(head)->last = (list)->last; \
790
} else { \
791
(head)->last->field.next = (list)->first; \
792
(head)->last = (list)->last; \
793
} \
794
(list)->first = NULL; \
795
(list)->last = NULL; \
796
} while (0)
797
798
#define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
799
800
/*!
801
\brief Inserts a whole list after a specific entry in a list
802
\param head This is a pointer to the list head structure
803
\param list This is a pointer to the list to be inserted.
804
\param elm This is a pointer to the entry after which the new list should
805
be inserted.
806
\param field This is the name of the field (declared using AST_LIST_ENTRY())
807
used to link entries of the lists together.
808
809
Note: The source list (the \a list parameter) will be empty after
810
calling this macro (the list entries are \b moved to the target list).
811
*/
812
#define AST_LIST_INSERT_LIST_AFTER(head, list, elm, field) do { \
813
(list)->last->field.next = (elm)->field.next; \
814
(elm)->field.next = (list)->first; \
815
if ((head)->last == elm) { \
816
(head)->last = (list)->last; \
817
} \
818
(list)->first = NULL; \
819
(list)->last = NULL; \
820
} while(0)
821
822
#define AST_RWLIST_INSERT_LIST_AFTER AST_LIST_INSERT_LIST_AFTER
823
824
/*!
825
* \brief Removes and returns the head entry from a list.
826
* \param head This is a pointer to the list head structure
827
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
828
* used to link entries of this list together.
829
*
830
* Removes the head entry from the list, and returns a pointer to it.
831
* This macro is safe to call on an empty list.
832
*/
833
#define AST_LIST_REMOVE_HEAD(head, field) ({ \
834
typeof((head)->first) __cur = (head)->first; \
835
if (__cur) { \
836
(head)->first = __cur->field.next; \
837
__cur->field.next = NULL; \
838
if ((head)->last == __cur) \
839
(head)->last = NULL; \
840
} \
841
__cur; \
842
})
843
844
#define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
845
846
/*!
847
* \brief Removes a specific entry from a list.
848
* \param head This is a pointer to the list head structure
849
* \param elm This is a pointer to the entry to be removed.
850
* \param field This is the name of the field (declared using AST_LIST_ENTRY())
851
* used to link entries of this list together.
852
* \retval elm if elm was in the list.
853
* \retval NULL if elm was not in the list or elm was NULL.
854
* \warning The removed entry is \b not freed.
855
*/
856
#define AST_LIST_REMOVE(head, elm, field) \
857
({ \
858
typeof(elm) __elm = (elm); \
859
if (__elm) { \
860
if ((head)->first == __elm) { \
861
(head)->first = __elm->field.next; \
862
__elm->field.next = NULL; \
863
if ((head)->last == __elm) { \
864
(head)->last = NULL; \
865
} \
866
} else { \
867
typeof(elm) __prev = (head)->first; \
868
while (__prev && __prev->field.next != __elm) { \
869
__prev = __prev->field.next; \
870
} \
871
if (__prev) { \
872
__prev->field.next = __elm->field.next; \
873
__elm->field.next = NULL; \
874
if ((head)->last == __elm) { \
875
(head)->last = __prev; \
876
} \
877
} else { \
878
__elm = NULL; \
879
} \
880
} \
881
} \
882
__elm; \
883
})
884
885
#define AST_RWLIST_REMOVE AST_LIST_REMOVE
886
887
#endif
/* _ASTERISK_LINKEDLISTS_H */
lock.h
Asterisk locking-related definitions:
Generated on Wed Dec 18 2024 20:04:16 for Asterisk - The Open Source Telephony Project by
1.9.4