Merge FreeBSD locking fixes (bug #1411)
[asterisk/asterisk.git] / include / asterisk / linkedlists.h
1 #ifndef ASTERISK_LINKEDLISTS_H
2 #define ASTERISK_LINKEDLISTS_H
3
4 #include <pthread.h>
5 #include <asterisk/lock.h>
6
7 #define AST_LIST_LOCK(head)                                             \
8         ast_mutex_lock(&head->lock) 
9         
10 #define AST_LIST_UNLOCK(head)                                           \
11         ast_mutex_unlock(&head->lock)
12
13 #define AST_LIST_HEAD(name, type)                                       \
14 struct name {                                                           \
15         struct type *first;                                             \
16         ast_mutex_t lock;                                               \
17 }
18
19 #define AST_LIST_HEAD_SET(head,entry) do {                              \
20         (head)->first=(entry);                                          \
21         ast_pthread_mutex_init(&(head)->lock,NULL);                             \
22 } while (0)
23
24 #define AST_LIST_ENTRY(type)                                            \
25 struct {                                                                \
26         struct type *next;                                              \
27 }
28  
29 #define AST_LIST_FIRST(head)    ((head)->first)
30
31 #define AST_LIST_NEXT(elm, field)       ((elm)->field.next)
32
33 #define AST_LIST_EMPTY(head)    (AST_LIST_FIRST(head) == NULL)
34
35 #define AST_LIST_TRAVERSE(head,var,field)                               \
36         for((var) = (head)->first; (var); (var) = (var)->field.next)
37
38 #define AST_LIST_HEAD_INIT(head) {                                              \
39         (head)->first = NULL;                                           \
40         ast_pthread_mutex_init(&(head)->lock,NULL);                             \
41 }
42
43 #define AST_LIST_INSERT_AFTER(listelm, elm, field) do {         \
44         (elm)->field.next = (listelm)->field.next;                      \
45         (listelm)->field.next = (elm);                          \
46 } while (0)
47
48 #define AST_LIST_INSERT_HEAD(head, elm, field) do {                     \
49                 (elm)->field.next = (head)->first;                      \
50                 (head)->first = (elm);                                  \
51 } while (0)
52
53 #define AST_LIST_INSERT_TAIL(head, elm, type, field) do {             \
54       struct type *curelm = (head)->first;                            \
55       if(!curelm) {                                                   \
56               AST_LIST_INSERT_HEAD(head, elm, field);                 \
57       } else {                                                        \
58               while ( curelm->field.next!=NULL ) {                    \
59                       curelm=curelm->field.next;                      \
60               }                                                       \
61               AST_LIST_INSERT_AFTER(curelm,elm,field);                \
62       }                                                               \
63 } while (0)
64
65
66 #define AST_LIST_REMOVE_HEAD(head, field) do {                                  \
67                 (head)->first = (head)->first->field.next;                      \
68         } while (0)
69
70 #define AST_LIST_REMOVE(head, elm, type, field) do {                    \
71         if ((head)->first == (elm)) {                                   \
72                 AST_LIST_REMOVE_HEAD((head), field);                    \
73         }                                                               \
74         else {                                                          \
75                 struct type *curelm = (head)->first;                    \
76                 while( curelm->field.next != (elm) )                    \
77                         curelm = curelm->field.next;                    \
78                 curelm->field.next =                                    \
79                     curelm->field.next->field.next;                     \
80         }                                                               \
81 } while (0)
82
83 #endif