diff options
author | Joshua Colp <jcolp@digium.com> | 2006-11-02 17:56:33 +0000 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2006-11-02 17:56:33 +0000 |
commit | ffceb28cfd63602cdb041b91b5670b887f1d602e (patch) | |
tree | d4211e163eaf4cabc9051ee1ac28453dc4341218 /include/asterisk/linkedlists.h | |
parent | 232e56f4964c71ffc09138976d85dc5cfcf94b23 (diff) |
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
Diffstat (limited to 'include/asterisk/linkedlists.h')
-rw-r--r-- | include/asterisk/linkedlists.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h index 865fafe72..268f827aa 100644 --- a/include/asterisk/linkedlists.h +++ b/include/asterisk/linkedlists.h @@ -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. @@ -61,6 +105,17 @@ 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. \param type This is the type of each list entry. @@ -87,6 +142,32 @@ struct name { \ } /*! + \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. \param type This is the type of each list entry. @@ -121,6 +202,15 @@ struct name { \ } /*! + \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 */ #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \ @@ -171,6 +261,48 @@ struct name { \ #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. This is the same as AST_LIST_HEAD_STATIC, except without the lock included. @@ -196,6 +328,20 @@ struct name { \ } 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 \param entry pointer to the list entry that will become the head of the list @@ -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 @@ -403,6 +569,19 @@ struct { \ } /*! + \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 @@ -417,6 +596,20 @@ struct { \ } /*! + \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 */ |