mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-16 23:08:32 +00:00
Add AST_RWLIST_* set of macros which implement linked lists using read/write locks, the actual list manipulation is still done via the old macros.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@46967 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -37,6 +37,28 @@
|
||||
*/
|
||||
#define AST_LIST_LOCK(head) \
|
||||
ast_mutex_lock(&(head)->lock)
|
||||
|
||||
/*!
|
||||
\brief Write locks a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
|
||||
This macro attempts to place an exclusive write lock in the
|
||||
list head structure pointed to by head.
|
||||
Returns non-zero on success, 0 on failure
|
||||
*/
|
||||
#define AST_RWLIST_WRLOCK(head) \
|
||||
ast_rwlock_wrlock(&(head)->lock)
|
||||
|
||||
/*!
|
||||
\brief Read locks a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
|
||||
This macro attempts to place a read lock in the
|
||||
list head structure pointed to by head.
|
||||
Returns non-zero on success, 0 on failure
|
||||
*/
|
||||
#define AST_RWLIST_RDLOCK(head) \
|
||||
ast_rwlock_rdlock(&(head)->lock)
|
||||
|
||||
/*!
|
||||
\brief Locks a list, without blocking if the list is locked.
|
||||
@@ -48,6 +70,28 @@
|
||||
*/
|
||||
#define AST_LIST_TRYLOCK(head) \
|
||||
ast_mutex_trylock(&(head)->lock)
|
||||
|
||||
/*!
|
||||
\brief Write locks a list, without blocking if the list is locked.
|
||||
\param head This is a pointer to the list head structure
|
||||
|
||||
This macro attempts to place an exclusive write lock in the
|
||||
list head structure pointed to by head.
|
||||
Returns non-zero on success, 0 on failure
|
||||
*/
|
||||
#define AST_RWLIST_TRYWRLOCK(head) \
|
||||
ast_rwlock_trywrlock(&(head)->lock)
|
||||
|
||||
/*!
|
||||
\brief Read locks a list, without blocking if the list is locked.
|
||||
\param head This is a pointer to the list head structure
|
||||
|
||||
This macro attempts to place a read lock in the
|
||||
list head structure pointed to by head.
|
||||
Returns non-zero on success, 0 on failure
|
||||
*/
|
||||
#define AST_RWLIST_TRYRDLOCK(head) \
|
||||
ast_rwlock_tryrdlock(&(head)->lock)
|
||||
|
||||
/*!
|
||||
\brief Attempts to unlock a list.
|
||||
@@ -60,6 +104,17 @@
|
||||
#define AST_LIST_UNLOCK(head) \
|
||||
ast_mutex_unlock(&(head)->lock)
|
||||
|
||||
/*!
|
||||
\brief Attempts to unlock a read/write based list.
|
||||
\param head This is a pointer to the list head structure
|
||||
|
||||
This macro attempts to remove a read or write lock from the
|
||||
list head structure pointed to by head. If the list
|
||||
was not locked by this thread, this macro has no effect.
|
||||
*/
|
||||
#define AST_RWLIST_UNLOCK(head) \
|
||||
ast_rwlock_unlock(&(head)->lock)
|
||||
|
||||
/*!
|
||||
\brief Defines a structure to be used to hold a list of specified type.
|
||||
\param name This will be the name of the defined structure.
|
||||
@@ -86,6 +141,32 @@ struct name { \
|
||||
ast_mutex_t lock; \
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Defines a structure to be used to hold a read/write list of specified type.
|
||||
\param name This will be the name of the defined structure.
|
||||
\param type This is the type of each list entry.
|
||||
|
||||
This macro creates a structure definition that can be used
|
||||
to hold a list of the entries of type \a type. It does not actually
|
||||
declare (allocate) a structure; to do that, either follow this
|
||||
macro with the desired name of the instance you wish to declare,
|
||||
or use the specified \a name to declare instances elsewhere.
|
||||
|
||||
Example usage:
|
||||
\code
|
||||
static AST_RWLIST_HEAD(entry_list, entry) entries;
|
||||
\endcode
|
||||
|
||||
This would define \c struct \c entry_list, and declare an instance of it named
|
||||
\a entries, all intended to hold a list of type \c struct \c entry.
|
||||
*/
|
||||
#define AST_RWLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *first; \
|
||||
struct type *last; \
|
||||
ast_rwlock_t lock; \
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Defines a structure to be used to hold a list of specified type (with no lock).
|
||||
\param name This will be the name of the defined structure.
|
||||
@@ -120,6 +201,15 @@ struct name { \
|
||||
.lock = AST_MUTEX_INIT_VALUE, \
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Defines initial values for a declaration of AST_RWLIST_HEAD
|
||||
*/
|
||||
#define AST_RWLIST_HEAD_INIT_VALUE { \
|
||||
.first = NULL, \
|
||||
.last = NULL, \
|
||||
.lock = AST_RWLOCK_INIT_VALUE, \
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
|
||||
*/
|
||||
@@ -170,6 +260,48 @@ struct name { \
|
||||
} name = AST_LIST_HEAD_INIT_VALUE
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
|
||||
\param name This will be the name of the defined structure.
|
||||
\param type This is the type of each list entry.
|
||||
|
||||
This macro creates a structure definition that can be used
|
||||
to hold a list of the entries of type \a type, and allocates an instance
|
||||
of it, initialized to be empty.
|
||||
|
||||
Example usage:
|
||||
\code
|
||||
static AST_RWLIST_HEAD_STATIC(entry_list, entry);
|
||||
\endcode
|
||||
|
||||
This would define \c struct \c entry_list, intended to hold a list of
|
||||
type \c struct \c entry.
|
||||
*/
|
||||
#ifndef AST_RWLOCK_INIT_VALUE
|
||||
#define AST_RWLIST_HEAD_STATIC(name, type) \
|
||||
struct name { \
|
||||
struct type *first; \
|
||||
struct type *last; \
|
||||
ast_rwlock_t lock; \
|
||||
} name; \
|
||||
static void __attribute__ ((constructor)) init_##name(void) \
|
||||
{ \
|
||||
AST_RWLIST_HEAD_INIT(&name); \
|
||||
} \
|
||||
static void __attribute__ ((destructor)) fini_##name(void) \
|
||||
{ \
|
||||
AST_RWLIST_HEAD_DESTROY(&name); \
|
||||
} \
|
||||
struct __dummy_##name
|
||||
#else
|
||||
#define AST_RWLIST_HEAD_STATIC(name, type) \
|
||||
struct name { \
|
||||
struct type *first; \
|
||||
struct type *last; \
|
||||
ast_rwlock_t lock; \
|
||||
} name = AST_RWLIST_HEAD_INIT_VALUE
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief Defines a structure to be used to hold a list of specified type, statically initialized.
|
||||
|
||||
@@ -195,6 +327,20 @@ struct name { \
|
||||
ast_mutex_init(&(head)->lock); \
|
||||
} while (0)
|
||||
|
||||
/*!
|
||||
\brief Initializes an rwlist head structure with a specified first entry.
|
||||
\param head This is a pointer to the list head structure
|
||||
\param entry pointer to the list entry that will become the head of the list
|
||||
|
||||
This macro initializes a list head structure by setting the head
|
||||
entry to the supplied value and recreating the embedded lock.
|
||||
*/
|
||||
#define AST_RWLIST_HEAD_SET(head, entry) do { \
|
||||
(head)->first = (entry); \
|
||||
(head)->last = (entry); \
|
||||
ast_rwlock_init(&(head)->lock); \
|
||||
} while (0)
|
||||
|
||||
/*!
|
||||
\brief Initializes a list head structure with a specified first entry.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -229,6 +375,8 @@ struct name { \
|
||||
struct { \
|
||||
struct type *next; \
|
||||
}
|
||||
|
||||
#define AST_RWLIST_ENTRY AST_LIST_ENTRY
|
||||
|
||||
/*!
|
||||
\brief Returns the first entry contained in a list.
|
||||
@@ -236,12 +384,16 @@ struct { \
|
||||
*/
|
||||
#define AST_LIST_FIRST(head) ((head)->first)
|
||||
|
||||
#define AST_RWLIST_FIRST AST_LIST_FIRST
|
||||
|
||||
/*!
|
||||
\brief Returns the last entry contained in a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
*/
|
||||
#define AST_LIST_LAST(head) ((head)->last)
|
||||
|
||||
#define AST_RWLIST_LAST AST_LIST_LAST
|
||||
|
||||
/*!
|
||||
\brief Returns the next entry in the list after the given entry.
|
||||
\param elm This is a pointer to the current entry.
|
||||
@@ -250,6 +402,8 @@ struct { \
|
||||
*/
|
||||
#define AST_LIST_NEXT(elm, field) ((elm)->field.next)
|
||||
|
||||
#define AST_RWLIST_NEXT AST_LIST_NEXT
|
||||
|
||||
/*!
|
||||
\brief Checks whether the specified list contains any entries.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -258,6 +412,8 @@ struct { \
|
||||
*/
|
||||
#define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
|
||||
|
||||
#define AST_RWLIST_EMPTY AST_LIST_EMPTY
|
||||
|
||||
/*!
|
||||
\brief Loops over (traverses) the entries in a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -297,6 +453,8 @@ struct { \
|
||||
#define AST_LIST_TRAVERSE(head,var,field) \
|
||||
for((var) = (head)->first; (var); (var) = (var)->field.next)
|
||||
|
||||
#define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
|
||||
|
||||
/*!
|
||||
\brief Loops safely over (traverses) the entries in a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -342,6 +500,8 @@ struct { \
|
||||
__list_next = (var) ? (var)->field.next : NULL \
|
||||
)
|
||||
|
||||
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
|
||||
|
||||
/*!
|
||||
\brief Removes the \a current entry from a list during a traversal.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -363,6 +523,8 @@ struct { \
|
||||
if (!__list_next) \
|
||||
(head)->last = __list_prev;
|
||||
|
||||
#define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
|
||||
|
||||
/*!
|
||||
\brief Inserts a list entry before the current entry during a traversal.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -384,11 +546,15 @@ struct { \
|
||||
__new_prev = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
|
||||
|
||||
/*!
|
||||
\brief Closes a safe loop traversal block.
|
||||
*/
|
||||
#define AST_LIST_TRAVERSE_SAFE_END }
|
||||
|
||||
#define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
|
||||
|
||||
/*!
|
||||
\brief Initializes a list head structure.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -402,6 +568,19 @@ struct { \
|
||||
ast_mutex_init(&(head)->lock); \
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Initializes an rwlist head structure.
|
||||
\param head This is a pointer to the list head structure
|
||||
|
||||
This macro initializes a list head structure by setting the head
|
||||
entry to \a NULL (empty list) and recreating the embedded lock.
|
||||
*/
|
||||
#define AST_RWLIST_HEAD_INIT(head) { \
|
||||
(head)->first = NULL; \
|
||||
(head)->last = NULL; \
|
||||
ast_rwlock_init(&(head)->lock); \
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Destroys a list head structure.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -416,6 +595,20 @@ struct { \
|
||||
ast_mutex_destroy(&(head)->lock); \
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Destroys an rwlist head structure.
|
||||
\param head This is a pointer to the list head structure
|
||||
|
||||
This macro destroys a list head structure by setting the head
|
||||
entry to \a NULL (empty list) and destroying the embedded lock.
|
||||
It does not free the structure from memory.
|
||||
*/
|
||||
#define AST_RWLIST_HEAD_DESTROY(head) { \
|
||||
(head)->first = NULL; \
|
||||
(head)->last = NULL; \
|
||||
ast_rwlock_destroy(&(head)->lock); \
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Initializes a list head structure.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -445,6 +638,8 @@ struct { \
|
||||
(head)->last = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
|
||||
|
||||
/*!
|
||||
\brief Inserts a list entry at the head of a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -459,6 +654,8 @@ struct { \
|
||||
(head)->last = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
|
||||
|
||||
/*!
|
||||
\brief Appends a list entry to the tail of a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -480,6 +677,8 @@ struct { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
|
||||
|
||||
/*!
|
||||
\brief Appends a whole list to the tail of a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -497,6 +696,8 @@ struct { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
|
||||
|
||||
/*!
|
||||
\brief Removes and returns the head entry from a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -517,6 +718,8 @@ struct { \
|
||||
cur; \
|
||||
})
|
||||
|
||||
#define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
|
||||
|
||||
/*!
|
||||
\brief Removes a specific entry from a list.
|
||||
\param head This is a pointer to the list head structure
|
||||
@@ -543,4 +746,6 @@ struct { \
|
||||
(elm)->field.next = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define AST_RWLIST_REMOVE AST_LIST_REMOVE
|
||||
|
||||
#endif /* _ASTERISK_LINKEDLISTS_H */
|
||||
|
||||
Reference in New Issue
Block a user