mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-20 08:40:16 +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:
@@ -38,6 +38,28 @@
|
|||||||
#define AST_LIST_LOCK(head) \
|
#define AST_LIST_LOCK(head) \
|
||||||
ast_mutex_lock(&(head)->lock)
|
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.
|
\brief Locks a list, without blocking if the list is locked.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -49,6 +71,28 @@
|
|||||||
#define AST_LIST_TRYLOCK(head) \
|
#define AST_LIST_TRYLOCK(head) \
|
||||||
ast_mutex_trylock(&(head)->lock)
|
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.
|
\brief Attempts to unlock a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -60,6 +104,17 @@
|
|||||||
#define AST_LIST_UNLOCK(head) \
|
#define AST_LIST_UNLOCK(head) \
|
||||||
ast_mutex_unlock(&(head)->lock)
|
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.
|
\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.
|
\param name This will be the name of the defined structure.
|
||||||
@@ -86,6 +141,32 @@ struct name { \
|
|||||||
ast_mutex_t lock; \
|
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).
|
\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.
|
\param name This will be the name of the defined structure.
|
||||||
@@ -120,6 +201,15 @@ struct name { \
|
|||||||
.lock = AST_MUTEX_INIT_VALUE, \
|
.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
|
\brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
|
||||||
*/
|
*/
|
||||||
@@ -170,6 +260,48 @@ struct name { \
|
|||||||
} name = AST_LIST_HEAD_INIT_VALUE
|
} name = AST_LIST_HEAD_INIT_VALUE
|
||||||
#endif
|
#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.
|
\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); \
|
ast_mutex_init(&(head)->lock); \
|
||||||
} while (0)
|
} 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.
|
\brief Initializes a list head structure with a specified first entry.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -230,18 +376,24 @@ struct { \
|
|||||||
struct type *next; \
|
struct type *next; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AST_RWLIST_ENTRY AST_LIST_ENTRY
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the first entry contained in a list.
|
\brief Returns the first entry contained in a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
*/
|
*/
|
||||||
#define AST_LIST_FIRST(head) ((head)->first)
|
#define AST_LIST_FIRST(head) ((head)->first)
|
||||||
|
|
||||||
|
#define AST_RWLIST_FIRST AST_LIST_FIRST
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the last entry contained in a list.
|
\brief Returns the last entry contained in a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
*/
|
*/
|
||||||
#define AST_LIST_LAST(head) ((head)->last)
|
#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.
|
\brief Returns the next entry in the list after the given entry.
|
||||||
\param elm This is a pointer to the current 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_LIST_NEXT(elm, field) ((elm)->field.next)
|
||||||
|
|
||||||
|
#define AST_RWLIST_NEXT AST_LIST_NEXT
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Checks whether the specified list contains any entries.
|
\brief Checks whether the specified list contains any entries.
|
||||||
\param head This is a pointer to the list head structure
|
\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_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
|
||||||
|
|
||||||
|
#define AST_RWLIST_EMPTY AST_LIST_EMPTY
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Loops over (traverses) the entries in a list.
|
\brief Loops over (traverses) the entries in a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -297,6 +453,8 @@ struct { \
|
|||||||
#define AST_LIST_TRAVERSE(head,var,field) \
|
#define AST_LIST_TRAVERSE(head,var,field) \
|
||||||
for((var) = (head)->first; (var); (var) = (var)->field.next)
|
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.
|
\brief Loops safely over (traverses) the entries in a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -342,6 +500,8 @@ struct { \
|
|||||||
__list_next = (var) ? (var)->field.next : NULL \
|
__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.
|
\brief Removes the \a current entry from a list during a traversal.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -363,6 +523,8 @@ struct { \
|
|||||||
if (!__list_next) \
|
if (!__list_next) \
|
||||||
(head)->last = __list_prev;
|
(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.
|
\brief Inserts a list entry before the current entry during a traversal.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -384,11 +546,15 @@ struct { \
|
|||||||
__new_prev = (elm); \
|
__new_prev = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Closes a safe loop traversal block.
|
\brief Closes a safe loop traversal block.
|
||||||
*/
|
*/
|
||||||
#define AST_LIST_TRAVERSE_SAFE_END }
|
#define AST_LIST_TRAVERSE_SAFE_END }
|
||||||
|
|
||||||
|
#define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Initializes a list head structure.
|
\brief Initializes a list head structure.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -402,6 +568,19 @@ struct { \
|
|||||||
ast_mutex_init(&(head)->lock); \
|
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.
|
\brief Destroys a list head structure.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -416,6 +595,20 @@ struct { \
|
|||||||
ast_mutex_destroy(&(head)->lock); \
|
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.
|
\brief Initializes a list head structure.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -445,6 +638,8 @@ struct { \
|
|||||||
(head)->last = (elm); \
|
(head)->last = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Inserts a list entry at the head of a list.
|
\brief Inserts a list entry at the head of a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -459,6 +654,8 @@ struct { \
|
|||||||
(head)->last = (elm); \
|
(head)->last = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Appends a list entry to the tail of a list.
|
\brief Appends a list entry to the tail of a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -480,6 +677,8 @@ struct { \
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Appends a whole list to the tail of a list.
|
\brief Appends a whole list to the tail of a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -497,6 +696,8 @@ struct { \
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Removes and returns the head entry from a list.
|
\brief Removes and returns the head entry from a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -517,6 +718,8 @@ struct { \
|
|||||||
cur; \
|
cur; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Removes a specific entry from a list.
|
\brief Removes a specific entry from a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -543,4 +746,6 @@ struct { \
|
|||||||
(elm)->field.next = NULL; \
|
(elm)->field.next = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define AST_RWLIST_REMOVE AST_LIST_REMOVE
|
||||||
|
|
||||||
#endif /* _ASTERISK_LINKEDLISTS_H */
|
#endif /* _ASTERISK_LINKEDLISTS_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user