Wed Jan 8 2020 09:49:46
Asterisk developer's documentation
Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
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 */
lock.h
Asterisk locking-related definitions:
include
asterisk
dlinkedlists.h
Generated by
1.8.5