Modify headers and macros, according to Russell's suggestions on the -dev list

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@187599 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/1.8.6
Tilghman Lesher 17 years ago
parent 4d74179f20
commit 1030a25ac9

@ -23,147 +23,151 @@
#include "asterisk/lock.h" #include "asterisk/lock.h"
/*! /*!
\file linkedlists.h * \file linkedlists.h
\brief A set of macros to manage forward-linked lists. * \brief A set of macros to manage forward-linked lists.
*/ */
/*! /*!
\brief Locks a list. * \brief Locks a list.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
*
This macro attempts to place an exclusive lock in the * This macro attempts to place an exclusive lock in the
list head structure pointed to by head. * list head structure pointed to by head.
\retval 0 on success * \retval 0 on success
\retval non-zero on failure * \retval non-zero on failure
*/ */
#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. * \brief Write locks a list.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
*
This macro attempts to place an exclusive write lock in the * This macro attempts to place an exclusive write lock in the
list head structure pointed to by head. * list head structure pointed to by head.
\retval 0 on success * \retval 0 on success
\retval non-zero on failure * \retval non-zero on failure
*/ */
#define AST_RWLIST_WRLOCK(head) \ #define AST_RWLIST_WRLOCK(head) \
ast_rwlock_wrlock(&(head)->lock) ast_rwlock_wrlock(&(head)->lock)
/*! /*!
\brief Write locks a list, with timeout. * \brief Write locks a list, with timeout.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
\param tv Pointer to a timeval structure * \param ts Pointer to a timespec structure
*
This macro attempts to place an exclusive write lock in the * This macro attempts to place an exclusive write lock in the
list head structure pointed to by head. * list head structure pointed to by head.
\retval 0 on success * \retval 0 on success
\retval non-zero on failure * \retval non-zero on failure
*
* \since 1.6.1
*/ */
#define AST_RWLIST_TIMEDWRLOCK(head,tv) ast_rwlock_timedwrlock(&(head)->lock, tv) #define AST_RWLIST_TIMEDWRLOCK(head, ts) ast_rwlock_timedwrlock(&(head)->lock, ts)
/*! /*!
\brief Read locks a list. * \brief Read locks a list.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
*
This macro attempts to place a read lock in the * This macro attempts to place a read lock in the
list head structure pointed to by head. * list head structure pointed to by head.
\retval 0 on success * \retval 0 on success
\retval non-zero on failure * \retval non-zero on failure
*/ */
#define AST_RWLIST_RDLOCK(head) \ #define AST_RWLIST_RDLOCK(head) \
ast_rwlock_rdlock(&(head)->lock) ast_rwlock_rdlock(&(head)->lock)
/*! /*!
\brief Read locks a list, with timeout. * \brief Read locks a list, with timeout.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
\param tv Pointer to a timeval structure * \param ts Pointer to a timespec structure
*
This macro attempts to place a read lock in the * This macro attempts to place a read lock in the
list head structure pointed to by head. * list head structure pointed to by head.
\retval 0 on success * \retval 0 on success
\retval non-zero on failure * \retval non-zero on failure
*
* \since 1.6.1
*/ */
#define AST_RWLIST_TIMEDRDLOCK(head,tv) \ #define AST_RWLIST_TIMEDRDLOCK(head, ts) \
ast_rwlock_timedrdlock(&(head)->lock, tv) ast_rwlock_timedrdlock(&(head)->lock, ts)
/*! /*!
\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
*
This macro attempts to place an exclusive lock in the * This macro attempts to place an exclusive lock in the
list head structure pointed to by head. * list head structure pointed to by head.
\retval 0 on success * \retval 0 on success
\retval non-zero on failure * \retval non-zero on failure
*/ */
#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. * \brief Write 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
*
This macro attempts to place an exclusive write lock in the * This macro attempts to place an exclusive write lock in the
list head structure pointed to by head. * list head structure pointed to by head.
\retval 0 on success * \retval 0 on success
\retval non-zero on failure * \retval non-zero on failure
*/ */
#define AST_RWLIST_TRYWRLOCK(head) \ #define AST_RWLIST_TRYWRLOCK(head) \
ast_rwlock_trywrlock(&(head)->lock) ast_rwlock_trywrlock(&(head)->lock)
/*! /*!
\brief Read locks a list, without blocking if the list is locked. * \brief Read 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
*
This macro attempts to place a read lock in the * This macro attempts to place a read lock in the
list head structure pointed to by head. * list head structure pointed to by head.
\retval 0 on success * \retval 0 on success
\retval non-zero on failure * \retval non-zero on failure
*/ */
#define AST_RWLIST_TRYRDLOCK(head) \ #define AST_RWLIST_TRYRDLOCK(head) \
ast_rwlock_tryrdlock(&(head)->lock) 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
*
This macro attempts to remove an exclusive lock from the * This macro attempts to remove an exclusive lock from the
list head structure pointed to by head. If the list * list head structure pointed to by head. If the list
was not locked by this thread, this macro has no effect. * was not locked by this thread, this macro has no effect.
*/ */
#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. * \brief Attempts to unlock a read/write based list.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
*
This macro attempts to remove a read or write lock from the * This macro attempts to remove a read or write lock from the
list head structure pointed to by head. If the list * list head structure pointed to by head. If the list
was not locked by this thread, this macro has no effect. * was not locked by this thread, this macro has no effect.
*/ */
#define AST_RWLIST_UNLOCK(head) \ #define AST_RWLIST_UNLOCK(head) \
ast_rwlock_unlock(&(head)->lock) 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.
\param type This is the type of each list entry. * \param type This is the type of each list entry.
*
This macro creates a structure definition that can be used * 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 * 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 * declare (allocate) a structure; to do that, either follow this
macro with the desired name of the instance you wish to declare, * macro with the desired name of the instance you wish to declare,
or use the specified \a name to declare instances elsewhere. * or use the specified \a name to declare instances elsewhere.
*
Example usage: * Example usage:
\code * \code
static AST_LIST_HEAD(entry_list, entry) entries; * static AST_LIST_HEAD(entry_list, entry) entries;
\endcode * \endcode
*
This would define \c struct \c entry_list, and declare an instance of it named * 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. * \a entries, all intended to hold a list of type \c struct \c entry.
*/ */
#define AST_LIST_HEAD(name, type) \ #define AST_LIST_HEAD(name, type) \
struct name { \ struct name { \
@ -173,23 +177,23 @@ struct name { \
} }
/*! /*!
\brief Defines a structure to be used to hold a read/write list of specified type. * \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 name This will be the name of the defined structure.
\param type This is the type of each list entry. * \param type This is the type of each list entry.
*
This macro creates a structure definition that can be used * 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 * 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 * declare (allocate) a structure; to do that, either follow this
macro with the desired name of the instance you wish to declare, * macro with the desired name of the instance you wish to declare,
or use the specified \a name to declare instances elsewhere. * or use the specified \a name to declare instances elsewhere.
*
Example usage: * Example usage:
\code * \code
static AST_RWLIST_HEAD(entry_list, entry) entries; * static AST_RWLIST_HEAD(entry_list, entry) entries;
\endcode * \endcode
*
This would define \c struct \c entry_list, and declare an instance of it named * 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. * \a entries, all intended to hold a list of type \c struct \c entry.
*/ */
#define AST_RWLIST_HEAD(name, type) \ #define AST_RWLIST_HEAD(name, type) \
struct name { \ struct name { \
@ -199,23 +203,23 @@ struct name { \
} }
/*! /*!
\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.
\param type This is the type of each list entry. * \param type This is the type of each list entry.
*
This macro creates a structure definition that can be used * 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 * 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 * declare (allocate) a structure; to do that, either follow this
macro with the desired name of the instance you wish to declare, * macro with the desired name of the instance you wish to declare,
or use the specified \a name to declare instances elsewhere. * or use the specified \a name to declare instances elsewhere.
*
Example usage: * Example usage:
\code * \code
static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries; * static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
\endcode * \endcode
*
This would define \c struct \c entry_list, and declare an instance of it named * 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. * \a entries, all intended to hold a list of type \c struct \c entry.
*/ */
#define AST_LIST_HEAD_NOLOCK(name, type) \ #define AST_LIST_HEAD_NOLOCK(name, type) \
struct name { \ struct name { \
@ -224,7 +228,7 @@ struct name { \
} }
/*! /*!
\brief Defines initial values for a declaration of AST_LIST_HEAD * \brief Defines initial values for a declaration of AST_LIST_HEAD
*/ */
#define AST_LIST_HEAD_INIT_VALUE { \ #define AST_LIST_HEAD_INIT_VALUE { \
.first = NULL, \ .first = NULL, \
@ -233,7 +237,7 @@ struct name { \
} }
/*! /*!
\brief Defines initial values for a declaration of AST_RWLIST_HEAD * \brief Defines initial values for a declaration of AST_RWLIST_HEAD
*/ */
#define AST_RWLIST_HEAD_INIT_VALUE { \ #define AST_RWLIST_HEAD_INIT_VALUE { \
.first = NULL, \ .first = NULL, \
@ -242,7 +246,7 @@ struct name { \
} }
/*! /*!
\brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK * \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
*/ */
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \ #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
.first = NULL, \ .first = NULL, \
@ -250,21 +254,21 @@ struct name { \
} }
/*! /*!
\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.
\param name This will be the name of the defined structure. * \param name This will be the name of the defined structure.
\param type This is the type of each list entry. * \param type This is the type of each list entry.
*
This macro creates a structure definition that can be used * 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 * to hold a list of the entries of type \a type, and allocates an instance
of it, initialized to be empty. * of it, initialized to be empty.
*
Example usage: * Example usage:
\code * \code
static AST_LIST_HEAD_STATIC(entry_list, entry); * static AST_LIST_HEAD_STATIC(entry_list, entry);
\endcode * \endcode
*
This would define \c struct \c entry_list, intended to hold a list of * This would define \c struct \c entry_list, intended to hold a list of
type \c struct \c entry. * type \c struct \c entry.
*/ */
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
#define AST_LIST_HEAD_STATIC(name, type) \ #define AST_LIST_HEAD_STATIC(name, type) \
@ -292,21 +296,21 @@ struct name { \
#endif #endif
/*! /*!
\brief Defines a structure to be used to hold a read/write list of specified type, statically initialized. * \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 name This will be the name of the defined structure.
\param type This is the type of each list entry. * \param type This is the type of each list entry.
*
This macro creates a structure definition that can be used * 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 * to hold a list of the entries of type \a type, and allocates an instance
of it, initialized to be empty. * of it, initialized to be empty.
*
Example usage: * Example usage:
\code * \code
static AST_RWLIST_HEAD_STATIC(entry_list, entry); * static AST_RWLIST_HEAD_STATIC(entry_list, entry);
\endcode * \endcode
*
This would define \c struct \c entry_list, intended to hold a list of * This would define \c struct \c entry_list, intended to hold a list of
type \c struct \c entry. * type \c struct \c entry.
*/ */
#ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
#define AST_RWLIST_HEAD_STATIC(name, type) \ #define AST_RWLIST_HEAD_STATIC(name, type) \
@ -334,9 +338,9 @@ struct name { \
#endif #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.
*
This is the same as AST_LIST_HEAD_STATIC, except without the lock included. * This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
*/ */
#define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \ #define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
struct name { \ struct name { \
@ -345,12 +349,12 @@ struct name { \
} name = AST_LIST_HEAD_NOLOCK_INIT_VALUE } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
/*! /*!
\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
\param entry pointer to the list entry that will become the head of the list * \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 * This macro initializes a list head structure by setting the head
entry to the supplied value and recreating the embedded lock. * entry to the supplied value and recreating the embedded lock.
*/ */
#define AST_LIST_HEAD_SET(head, entry) do { \ #define AST_LIST_HEAD_SET(head, entry) do { \
(head)->first = (entry); \ (head)->first = (entry); \
@ -359,12 +363,12 @@ struct name { \
} while (0) } while (0)
/*! /*!
\brief Initializes an rwlist head structure with a specified first entry. * \brief Initializes an rwlist 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
\param entry pointer to the list entry that will become the head of the list * \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 * This macro initializes a list head structure by setting the head
entry to the supplied value and recreating the embedded lock. * entry to the supplied value and recreating the embedded lock.
*/ */
#define AST_RWLIST_HEAD_SET(head, entry) do { \ #define AST_RWLIST_HEAD_SET(head, entry) do { \
(head)->first = (entry); \ (head)->first = (entry); \
@ -373,12 +377,12 @@ struct name { \
} while (0) } 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
\param entry pointer to the list entry that will become the head of the list * \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 * This macro initializes a list head structure by setting the head
entry to the supplied value. * entry to the supplied value.
*/ */
#define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \ #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
(head)->first = (entry); \ (head)->first = (entry); \
@ -386,21 +390,21 @@ struct name { \
} while (0) } while (0)
/*! /*!
\brief Declare a forward link structure inside a list entry. * \brief Declare a forward link structure inside a list entry.
\param type This is the type of each list entry. * \param type This is the type of each list entry.
*
This macro declares a structure to be used to link list entries together. * This macro declares a structure to be used to link list entries together.
It must be used inside the definition of the structure named in * It must be used inside the definition of the structure named in
\a type, as follows: * \a type, as follows:
*
\code * \code
struct list_entry { * struct list_entry {
... ...
AST_LIST_ENTRY(list_entry) list; AST_LIST_ENTRY(list_entry) list;
} * }
\endcode * \endcode
*
The field name \a list here is arbitrary, and can be anything you wish. * The field name \a list here is arbitrary, and can be anything you wish.
*/ */
#define AST_LIST_ENTRY(type) \ #define AST_LIST_ENTRY(type) \
struct { \ struct { \
@ -410,78 +414,78 @@ struct { \
#define AST_RWLIST_ENTRY AST_LIST_ENTRY #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 #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 #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.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*/ */
#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 #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
*
\return non-zero if the list has entries * \return non-zero if the list has entries
\return zero if not. * \return zero if not.
*/ */
#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 #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
\param var This is the name of the variable that will hold a pointer to the * \param var This is the name of the variable that will hold a pointer to the
current list entry on each iteration. It must be declared before calling * current list entry on each iteration. It must be declared before calling
this macro. * this macro.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*
This macro is use to loop over (traverse) the entries in a list. It uses a * This macro is use to loop over (traverse) the entries in a list. It uses a
\a for loop, and supplies the enclosed code with a pointer to each list * \a for loop, and supplies the enclosed code with a pointer to each list
entry as it loops. It is typically used as follows: * entry as it loops. It is typically used as follows:
\code * \code
static AST_LIST_HEAD(entry_list, list_entry) entries; * static AST_LIST_HEAD(entry_list, list_entry) entries;
... * ...
struct list_entry { * struct list_entry {
... ...
AST_LIST_ENTRY(list_entry) list; AST_LIST_ENTRY(list_entry) list;
} * }
... * ...
struct list_entry *current; * struct list_entry *current;
... * ...
AST_LIST_TRAVERSE(&entries, current, list) { * AST_LIST_TRAVERSE(&entries, current, list) {
(do something with current here) (do something with current here)
} * }
\endcode * \endcode
\warning If you modify the forward-link pointer contained in the \a current entry while * \warning If you modify the forward-link pointer contained in the \a current entry while
inside the loop, the behavior will be unpredictable. At a minimum, the following * inside the loop, the behavior will be unpredictable. At a minimum, the following
macros will modify the forward-link pointer, and should not be used inside * macros will modify the forward-link pointer, and should not be used inside
AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without * AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
careful consideration of their consequences: * careful consideration of their consequences:
\li AST_LIST_NEXT() (when used as an lvalue) * \li AST_LIST_NEXT() (when used as an lvalue)
\li AST_LIST_INSERT_AFTER() * \li AST_LIST_INSERT_AFTER()
\li AST_LIST_INSERT_HEAD() * \li AST_LIST_INSERT_HEAD()
\li AST_LIST_INSERT_TAIL() * \li AST_LIST_INSERT_TAIL()
\li AST_LIST_INSERT_SORTALPHA() * \li AST_LIST_INSERT_SORTALPHA()
*/ */
#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)
@ -489,37 +493,37 @@ struct { \
#define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE #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
\param var This is the name of the variable that will hold a pointer to the * \param var This is the name of the variable that will hold a pointer to the
current list entry on each iteration. It must be declared before calling * current list entry on each iteration. It must be declared before calling
this macro. * this macro.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*
This macro is used to safely loop over (traverse) the entries in a list. It * This macro is used to safely loop over (traverse) the entries in a list. It
uses a \a for loop, and supplies the enclosed code with a pointer to each list * uses a \a for loop, and supplies the enclosed code with a pointer to each list
entry as it loops. It is typically used as follows: * entry as it loops. It is typically used as follows:
*
\code * \code
static AST_LIST_HEAD(entry_list, list_entry) entries; * static AST_LIST_HEAD(entry_list, list_entry) entries;
... * ...
struct list_entry { * struct list_entry {
... ...
AST_LIST_ENTRY(list_entry) list; AST_LIST_ENTRY(list_entry) list;
} * }
... * ...
struct list_entry *current; * struct list_entry *current;
... * ...
AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) { * AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
(do something with current here) (do something with current here)
} * }
AST_LIST_TRAVERSE_SAFE_END; * AST_LIST_TRAVERSE_SAFE_END;
\endcode * \endcode
*
It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify * It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
(or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by * (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
the \a current pointer without affecting the loop traversal. * the \a current pointer without affecting the loop traversal.
*/ */
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \ #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
typeof((head)) __list_head = head; \ typeof((head)) __list_head = head; \
@ -537,14 +541,14 @@ struct { \
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN #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 field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*
\note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN() * \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
block; it is used to unlink the current entry from the list without affecting * block; it is used to unlink the current entry from the list without affecting
the list traversal (and without having to re-traverse the list to modify the * the list traversal (and without having to re-traverse the list to modify the
previous entry, if any). * previous entry, if any).
*/ */
#define AST_LIST_REMOVE_CURRENT(field) do { \ #define AST_LIST_REMOVE_CURRENT(field) do { \
__new_prev->field.next = NULL; \ __new_prev->field.next = NULL; \
@ -568,13 +572,13 @@ struct { \
#define AST_RWLIST_MOVE_CURRENT AST_LIST_MOVE_CURRENT #define AST_RWLIST_MOVE_CURRENT AST_LIST_MOVE_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 elm This is a pointer to the entry to be inserted. * \param elm This is a pointer to the entry to be inserted.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*
\note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN() * \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
block. * block.
*/ */
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field) do { \ #define AST_LIST_INSERT_BEFORE_CURRENT(elm, field) do { \
if (__list_prev) { \ if (__list_prev) { \
@ -590,18 +594,18 @@ struct { \
#define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT #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 #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
*
This macro initializes a list head structure by setting the head * This macro initializes a list head structure by setting the head
entry to \a NULL (empty list) and recreating the embedded lock. * entry to \a NULL (empty list) and recreating the embedded lock.
*/ */
#define AST_LIST_HEAD_INIT(head) { \ #define AST_LIST_HEAD_INIT(head) { \
(head)->first = NULL; \ (head)->first = NULL; \
@ -610,11 +614,11 @@ struct { \
} }
/*! /*!
\brief Initializes an rwlist head structure. * \brief Initializes an rwlist head structure.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
*
This macro initializes a list head structure by setting the head * This macro initializes a list head structure by setting the head
entry to \a NULL (empty list) and recreating the embedded lock. * entry to \a NULL (empty list) and recreating the embedded lock.
*/ */
#define AST_RWLIST_HEAD_INIT(head) { \ #define AST_RWLIST_HEAD_INIT(head) { \
(head)->first = NULL; \ (head)->first = NULL; \
@ -623,12 +627,12 @@ struct { \
} }
/*! /*!
\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
*
This macro destroys a list head structure by setting the head * This macro destroys a list head structure by setting the head
entry to \a NULL (empty list) and destroying the embedded lock. * entry to \a NULL (empty list) and destroying the embedded lock.
It does not free the structure from memory. * It does not free the structure from memory.
*/ */
#define AST_LIST_HEAD_DESTROY(head) { \ #define AST_LIST_HEAD_DESTROY(head) { \
(head)->first = NULL; \ (head)->first = NULL; \
@ -637,12 +641,12 @@ struct { \
} }
/*! /*!
\brief Destroys an rwlist head structure. * \brief Destroys an rwlist head structure.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
*
This macro destroys a list head structure by setting the head * This macro destroys a list head structure by setting the head
entry to \a NULL (empty list) and destroying the embedded lock. * entry to \a NULL (empty list) and destroying the embedded lock.
It does not free the structure from memory. * It does not free the structure from memory.
*/ */
#define AST_RWLIST_HEAD_DESTROY(head) { \ #define AST_RWLIST_HEAD_DESTROY(head) { \
(head)->first = NULL; \ (head)->first = NULL; \
@ -651,12 +655,12 @@ struct { \
} }
/*! /*!
\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
*
This macro initializes a list head structure by setting the head * This macro initializes a list head structure by setting the head
entry to \a NULL (empty list). There is no embedded lock handling * entry to \a NULL (empty list). There is no embedded lock handling
with this macro. * with this macro.
*/ */
#define AST_LIST_HEAD_INIT_NOLOCK(head) { \ #define AST_LIST_HEAD_INIT_NOLOCK(head) { \
(head)->first = NULL; \ (head)->first = NULL; \
@ -664,13 +668,13 @@ struct { \
} }
/*! /*!
\brief Inserts a list entry after a given entry. * \brief Inserts a list entry after a given entry.
\param head This is a pointer to the list head structure * \param head This is a pointer to the list head structure
\param listelm This is a pointer to the entry after which the new entry should * \param listelm This is a pointer to the entry after which the new entry should
be inserted. * be inserted.
\param elm This is a pointer to the entry to be inserted. * \param elm This is a pointer to the entry to be inserted.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*/ */
#define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \ #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.next = (listelm)->field.next; \ (elm)->field.next = (listelm)->field.next; \
@ -682,11 +686,11 @@ struct { \
#define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER #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
\param elm This is a pointer to the entry to be inserted. * \param elm This is a pointer to the entry to be inserted.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*/ */
#define AST_LIST_INSERT_HEAD(head, elm, field) do { \ #define AST_LIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.next = (head)->first; \ (elm)->field.next = (head)->first; \
@ -698,15 +702,15 @@ struct { \
#define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD #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
\param elm This is a pointer to the entry to be appended. * \param elm This is a pointer to the entry to be appended.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*
Note: The link field in the appended entry is \b not modified, so if it is * Note: The link field in the appended entry is \b not modified, so if it is
actually the head of a list itself, the entire list will be appended * actually the head of a list itself, the entire list will be appended
temporarily (until the next AST_LIST_INSERT_TAIL is performed). * temporarily (until the next AST_LIST_INSERT_TAIL is performed).
*/ */
#define AST_LIST_INSERT_TAIL(head, elm, field) do { \ #define AST_LIST_INSERT_TAIL(head, elm, field) do { \
if (!(head)->first) { \ if (!(head)->first) { \
@ -751,14 +755,14 @@ struct { \
#define AST_RWLIST_INSERT_SORTALPHA AST_LIST_INSERT_SORTALPHA #define AST_RWLIST_INSERT_SORTALPHA AST_LIST_INSERT_SORTALPHA
/*! /*!
\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
\param list This is a pointer to the list to be appended. * \param list This is a pointer to the list to be appended.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*
Note: The source list (the \a list parameter) will be empty after * Note: The source list (the \a list parameter) will be empty after
calling this macro (the list entries are \b moved to the target list). * calling this macro (the list entries are \b moved to the target list).
*/ */
#define AST_LIST_APPEND_LIST(head, list, field) do { \ #define AST_LIST_APPEND_LIST(head, list, field) do { \
if (!(head)->first) { \ if (!(head)->first) { \
@ -775,13 +779,13 @@ struct { \
#define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST #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
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
*
Removes the head entry from the list, and returns a pointer to it. * Removes the head entry from the list, and returns a pointer to it.
This macro is safe to call on an empty list. * This macro is safe to call on an empty list.
*/ */
#define AST_LIST_REMOVE_HEAD(head, field) ({ \ #define AST_LIST_REMOVE_HEAD(head, field) ({ \
typeof((head)->first) cur = (head)->first; \ typeof((head)->first) cur = (head)->first; \
@ -797,12 +801,12 @@ struct { \
#define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD #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
\param elm This is a pointer to the entry to be removed. * \param elm This is a pointer to the entry to be removed.
\param field This is the name of the field (declared using AST_LIST_ENTRY()) * \param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together. * used to link entries of this list together.
\warning The removed entry is \b not freed nor modified in any way. * \warning The removed entry is \b not freed nor modified in any way.
*/ */
#define AST_LIST_REMOVE(head, elm, field) ({ \ #define AST_LIST_REMOVE(head, elm, field) ({ \
__typeof(elm) __res = NULL; \ __typeof(elm) __res = NULL; \

@ -1335,6 +1335,7 @@ static inline int _ast_rwlock_wrlock(ast_rwlock_t *t, const char *name,
if (lt->reentrancy) { if (lt->reentrancy) {
ast_reentrancy_lock(lt); ast_reentrancy_lock(lt);
bt = &lt->backtrace[lt->reentrancy-1]; bt = &lt->backtrace[lt->reentrancy-1];
ast_reentrancy_unlock(lt);
} else { } else {
bt = NULL; bt = NULL;
} }
@ -1413,6 +1414,7 @@ static inline int _ast_rwlock_timedrdlock(ast_rwlock_t *t, const char *name,
if (lt->reentrancy) { if (lt->reentrancy) {
ast_reentrancy_lock(lt); ast_reentrancy_lock(lt);
bt = &lt->backtrace[lt->reentrancy-1]; bt = &lt->backtrace[lt->reentrancy-1];
ast_reentrancy_unlock(lt);
} else { } else {
bt = NULL; bt = NULL;
} }
@ -1491,6 +1493,7 @@ static inline int _ast_rwlock_timedwrlock(ast_rwlock_t *t, const char *name,
if (lt->reentrancy) { if (lt->reentrancy) {
ast_reentrancy_lock(lt); ast_reentrancy_lock(lt);
bt = &lt->backtrace[lt->reentrancy-1]; bt = &lt->backtrace[lt->reentrancy-1];
ast_reentrancy_unlock(lt);
} else { } else {
bt = NULL; bt = NULL;
} }

@ -1104,7 +1104,7 @@ int ast_app_group_update(struct ast_channel *old, struct ast_channel *new)
ast_free(gi); ast_free(gi);
} }
} }
AST_RWLIST_TRAVERSE_SAFE_END AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&groups); AST_RWLIST_UNLOCK(&groups);
return 0; return 0;

@ -592,7 +592,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
ast_audiohook_write_frame(audiohook, direction, middle_frame); ast_audiohook_write_frame(audiohook, direction, middle_frame);
ast_audiohook_unlock(audiohook); ast_audiohook_unlock(audiohook);
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END;
/* If this frame is being written out to the channel then we need to use whisper sources */ /* If this frame is being written out to the channel then we need to use whisper sources */
if (direction == AST_AUDIOHOOK_DIRECTION_WRITE && !AST_LIST_EMPTY(&audiohook_list->whisper_list)) { if (direction == AST_AUDIOHOOK_DIRECTION_WRITE && !AST_LIST_EMPTY(&audiohook_list->whisper_list)) {
@ -615,7 +615,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
} }
ast_audiohook_unlock(audiohook); ast_audiohook_unlock(audiohook);
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END;
/* We take all of the combined whisper sources and combine them into the audio being written out */ /* We take all of the combined whisper sources and combine them into the audio being written out */
for (i = 0, data1 = middle_frame->data.ptr, data2 = combine_buf; i < samples; i++, data1++, data2++) for (i = 0, data1 = middle_frame->data.ptr, data2 = combine_buf; i < samples; i++, data1++, data2++)
ast_slinear_saturated_add(data1, data2); ast_slinear_saturated_add(data1, data2);
@ -638,7 +638,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
audiohook->manipulate_callback(audiohook, chan, middle_frame, direction); audiohook->manipulate_callback(audiohook, chan, middle_frame, direction);
ast_audiohook_unlock(audiohook); ast_audiohook_unlock(audiohook);
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END;
end_frame = middle_frame; end_frame = middle_frame;
} }

@ -108,7 +108,7 @@ int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
break; break;
} }
} }
AST_RWLIST_TRAVERSE_SAFE_END AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&bridge_technologies); AST_RWLIST_UNLOCK(&bridge_technologies);

@ -2933,7 +2933,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
AST_LIST_REMOVE_CURRENT(frame_list); AST_LIST_REMOVE_CURRENT(frame_list);
break; break;
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END;
if (!f) { if (!f) {
/* There were no acceptable frames on the readq. */ /* There were no acceptable frames on the readq. */

@ -3353,7 +3353,7 @@ static int park_exec_full(struct ast_channel *chan, void *data, struct ast_parki
break; break;
} }
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&parkinglot->parkings); AST_LIST_UNLOCK(&parkinglot->parkings);
if (pu) { if (pu) {

@ -399,7 +399,7 @@ void ast_http_uri_unlink_all_with_key(const char *key)
ast_free(urih); ast_free(urih);
} }
} }
AST_RWLIST_TRAVERSE_SAFE_END AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&uris); AST_RWLIST_UNLOCK(&uris);
} }

@ -3381,7 +3381,7 @@ int ast_manager_unregister(char *action)
break; break;
} }
} }
AST_RWLIST_TRAVERSE_SAFE_END AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&actions); AST_RWLIST_UNLOCK(&actions);
return 0; return 0;

@ -3967,7 +3967,7 @@ int ast_extension_state_del(int id, ast_state_cb_type callback)
break; break;
} }
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END;
} else { /* callback with extension, find the callback based on ID */ } else { /* callback with extension, find the callback based on ID */
struct ast_hint *hint; struct ast_hint *hint;
AST_RWLIST_TRAVERSE(&hints, hint, list) { AST_RWLIST_TRAVERSE(&hints, hint, list) {
@ -3977,7 +3977,7 @@ int ast_extension_state_del(int id, ast_state_cb_type callback)
break; break;
} }
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END;
if (p_cur) if (p_cur)
break; break;
@ -8279,7 +8279,7 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context
ast_free(sw); ast_free(sw);
} }
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END;
if (tmp->root_table) { /* it is entirely possible that the context is EMPTY */ if (tmp->root_table) { /* it is entirely possible that the context is EMPTY */
exten_iter = ast_hashtab_start_traversal(tmp->root_table); exten_iter = ast_hashtab_start_traversal(tmp->root_table);

Loading…
Cancel
Save