Mon Jun 27 16:50:53 2011

Asterisk developer's documentation


dlinkedlists.h

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2007, Digium, Inc.
00005  *
00006  * Steve Murphy <murf@digium.com>
00007  *
00008  * Doubly-Linked List Macros--
00009  * Based on linkedlists.h (to the point of plagiarism!), which is by:
00010  *
00011  * Mark Spencer <markster@digium.com>
00012  * Kevin P. Fleming <kpfleming@digium.com>
00013  *
00014  * See http://www.asterisk.org for more information about
00015  * the Asterisk project. Please do not directly contact
00016  * any of the maintainers of this project for assistance;
00017  * the project provides a web site, mailing lists and IRC
00018  * channels for your use.
00019  *
00020  * This program is free software, distributed under the terms of
00021  * the GNU General Public License Version 2. See the LICENSE file
00022  * at the top of the source tree.
00023  */
00024 
00025 #ifndef ASTERISK_DLINKEDLISTS_H
00026 #define ASTERISK_DLINKEDLISTS_H
00027 
00028 #include "asterisk/lock.h"
00029 
00030 /*!
00031   \file dlinkedlists.h
00032   \brief A set of macros to manage doubly-linked lists.
00033 */
00034 
00035 /*!
00036   \brief Locks a list.
00037   \param head This is a pointer to the list head structure
00038 
00039   This macro attempts to place an exclusive lock in the
00040   list head structure pointed to by head.
00041   \retval 0 on success
00042   \retval non-zero on failure
00043   \since 1.6.1
00044 */
00045 #define AST_DLLIST_LOCK(head)                \
00046    ast_mutex_lock(&(head)->lock)
00047 
00048 /*!
00049   \brief Write locks a list.
00050   \param head This is a pointer to the list head structure
00051 
00052   This macro attempts to place an exclusive write lock in the
00053   list head structure pointed to by head.
00054   \retval 0 on success
00055   \retval non-zero on failure
00056   \since 1.6.1
00057 */
00058 #define AST_RWDLLIST_WRLOCK(head)                                         \
00059         ast_rwlock_wrlock(&(head)->lock)
00060 
00061 /*!
00062   \brief Read locks a list.
00063   \param head This is a pointer to the list head structure
00064 
00065   This macro attempts to place a read lock in the
00066   list head structure pointed to by head.
00067   \retval 0 on success
00068   \retval non-zero on failure
00069   \since 1.6.1
00070 */
00071 #define AST_RWDLLIST_RDLOCK(head)                                         \
00072         ast_rwlock_rdlock(&(head)->lock)
00073 
00074 /*!
00075   \brief Locks a list, without blocking if the list is locked.
00076   \param head This is a pointer to the list head structure
00077 
00078   This macro attempts to place an exclusive lock in the
00079   list head structure pointed to by head.
00080   \retval 0 on success
00081   \retval non-zero on failure
00082   \since 1.6.1
00083 */
00084 #define AST_DLLIST_TRYLOCK(head)                \
00085    ast_mutex_trylock(&(head)->lock)
00086 
00087 /*!
00088   \brief Write locks a list, without blocking if the list is locked.
00089   \param head This is a pointer to the list head structure
00090 
00091   This macro attempts to place an exclusive write lock in the
00092   list head structure pointed to by head.
00093   \retval 0 on success
00094   \retval non-zero on failure
00095   \since 1.6.1
00096 */
00097 #define AST_RWDLLIST_TRYWRLOCK(head)                                      \
00098         ast_rwlock_trywrlock(&(head)->lock)
00099 
00100 /*!
00101   \brief Read locks a list, without blocking if the list is locked.
00102   \param head This is a pointer to the list head structure
00103 
00104   This macro attempts to place a read lock in the
00105   list head structure pointed to by head.
00106   \retval 0 on success
00107   \retval non-zero on failure
00108   \since 1.6.1
00109 */
00110 #define AST_RWDLLIST_TRYRDLOCK(head)                                      \
00111         ast_rwlock_tryrdlock(&(head)->lock)
00112 
00113 /*!
00114   \brief Attempts to unlock a list.
00115   \param head This is a pointer to the list head structure
00116 
00117   This macro attempts to remove an exclusive lock from the
00118   list head structure pointed to by head. If the list
00119   was not locked by this thread, this macro has no effect.
00120   \since 1.6.1
00121 */
00122 #define AST_DLLIST_UNLOCK(head)                 \
00123    ast_mutex_unlock(&(head)->lock)
00124 
00125 /*!
00126   \brief Attempts to unlock a read/write based list.
00127   \param head This is a pointer to the list head structure
00128 
00129   This macro attempts to remove a read or write lock from the
00130   list head structure pointed to by head. If the list
00131   was not locked by this thread, this macro has no effect.
00132   \since 1.6.1
00133 */
00134 #define AST_RWDLLIST_UNLOCK(head)                                         \
00135         ast_rwlock_unlock(&(head)->lock)
00136 
00137 /*!
00138   \brief Defines a structure to be used to hold a list of specified type.
00139   \param name This will be the name of the defined structure.
00140   \param type This is the type of each list entry.
00141 
00142   This macro creates a structure definition that can be used
00143   to hold a list of the entries of type \a type. It does not actually
00144   declare (allocate) a structure; to do that, either follow this
00145   macro with the desired name of the instance you wish to declare,
00146   or use the specified \a name to declare instances elsewhere.
00147 
00148   Example usage:
00149   \code
00150   static AST_DLLIST_HEAD(entry_list, entry) entries;
00151   \endcode
00152 
00153   This would define \c struct \c entry_list, and declare an instance of it named
00154   \a entries, all intended to hold a list of type \c struct \c entry.
00155   \since 1.6.1
00156 */
00157 #define AST_DLLIST_HEAD(name, type)             \
00158 struct name {                       \
00159    struct type *first;                 \
00160    struct type *last;                  \
00161    ast_mutex_t lock;                \
00162 }
00163 
00164 /*!
00165   \brief Defines a structure to be used to hold a read/write list of specified type.
00166   \param name This will be the name of the defined structure.
00167   \param type This is the type of each list entry.
00168 
00169   This macro creates a structure definition that can be used
00170   to hold a list of the entries of type \a type. It does not actually
00171   declare (allocate) a structure; to do that, either follow this
00172   macro with the desired name of the instance you wish to declare,
00173   or use the specified \a name to declare instances elsewhere.
00174 
00175   Example usage:
00176   \code
00177   static AST_RWDLLIST_HEAD(entry_list, entry) entries;
00178   \endcode
00179 
00180   This would define \c struct \c entry_list, and declare an instance of it named
00181   \a entries, all intended to hold a list of type \c struct \c entry.
00182   \since 1.6.1
00183 */
00184 #define AST_RWDLLIST_HEAD(name, type)                                     \
00185 struct name {                                                           \
00186         struct type *first;                                             \
00187         struct type *last;                                              \
00188         ast_rwlock_t lock;                                              \
00189 }
00190 
00191 /*!
00192   \brief Defines a structure to be used to hold a list of specified type (with no lock).
00193   \param name This will be the name of the defined structure.
00194   \param type This is the type of each list entry.
00195 
00196   This macro creates a structure definition that can be used
00197   to hold a list of the entries of type \a type. It does not actually
00198   declare (allocate) a structure; to do that, either follow this
00199   macro with the desired name of the instance you wish to declare,
00200   or use the specified \a name to declare instances elsewhere.
00201 
00202   Example usage:
00203   \code
00204   static AST_DLLIST_HEAD_NOLOCK(entry_list, entry) entries;
00205   \endcode
00206 
00207   This would define \c struct \c entry_list, and declare an instance of it named
00208   \a entries, all intended to hold a list of type \c struct \c entry.
00209   \since 1.6.1
00210 */
00211 #define AST_DLLIST_HEAD_NOLOCK(name, type)            \
00212 struct name {                       \
00213    struct type *first;                 \
00214    struct type *last;                  \
00215 }
00216 
00217 /*!
00218   \brief Defines initial values for a declaration of AST_DLLIST_HEAD
00219   \since 1.6.1
00220 */
00221 #define AST_DLLIST_HEAD_INIT_VALUE  {     \
00222    .first = NULL,             \
00223    .last = NULL,              \
00224    .lock = AST_MUTEX_INIT_VALUE,       \
00225    }
00226 
00227 /*!
00228   \brief Defines initial values for a declaration of AST_RWDLLIST_HEAD
00229   \since 1.6.1
00230 */
00231 #define AST_RWDLLIST_HEAD_INIT_VALUE      {               \
00232         .first = NULL,                                  \
00233         .last = NULL,                                   \
00234         .lock = AST_RWLOCK_INIT_VALUE,                  \
00235         }
00236 
00237 /*!
00238   \brief Defines initial values for a declaration of AST_DLLIST_HEAD_NOLOCK
00239   \since 1.6.1
00240 */
00241 #define AST_DLLIST_HEAD_NOLOCK_INIT_VALUE {  \
00242    .first = NULL,             \
00243    .last = NULL,              \
00244    }
00245 
00246 /*!
00247   \brief Defines a structure to be used to hold a list of specified type, statically initialized.
00248   \param name This will be the name of the defined structure.
00249   \param type This is the type of each list entry.
00250 
00251   This macro creates a structure definition that can be used
00252   to hold a list of the entries of type \a type, and allocates an instance
00253   of it, initialized to be empty.
00254 
00255   Example usage:
00256   \code
00257   static AST_DLLIST_HEAD_STATIC(entry_list, entry);
00258   \endcode
00259 
00260   This would define \c struct \c entry_list, intended to hold a list of
00261   type \c struct \c entry.
00262   \since 1.6.1
00263 */
00264 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
00265 #define AST_DLLIST_HEAD_STATIC(name, type)            \
00266 struct name {                       \
00267    struct type *first;                 \
00268    struct type *last;                  \
00269    ast_mutex_t lock;                \
00270 } name;                          \
00271 static void  __attribute__((constructor)) __init_##name(void)     \
00272 {                          \
00273         AST_DLLIST_HEAD_INIT(&name);               \
00274 }                          \
00275 static void  __attribute__((destructor)) __fini_##name(void)      \
00276 {                          \
00277         AST_DLLIST_HEAD_DESTROY(&name);               \
00278 }                          \
00279 struct __dummy_##name
00280 #else
00281 #define AST_DLLIST_HEAD_STATIC(name, type)            \
00282 struct name {                       \
00283    struct type *first;                 \
00284    struct type *last;                  \
00285    ast_mutex_t lock;                \
00286 } name = AST_DLLIST_HEAD_INIT_VALUE
00287 #endif
00288 
00289 /*!
00290   \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
00291   \param name This will be the name of the defined structure.
00292   \param type This is the type of each list entry.
00293 
00294   This macro creates a structure definition that can be used
00295   to hold a list of the entries of type \a type, and allocates an instance
00296   of it, initialized to be empty.
00297 
00298   Example usage:
00299   \code
00300   static AST_RWDLLIST_HEAD_STATIC(entry_list, entry);
00301   \endcode
00302 
00303   This would define \c struct \c entry_list, intended to hold a list of
00304   type \c struct \c entry.
00305   \since 1.6.1
00306 */
00307 #ifndef AST_RWLOCK_INIT_VALUE
00308 #define AST_RWDLLIST_HEAD_STATIC(name, type)                              \
00309 struct name {                                                           \
00310         struct type *first;                                             \
00311         struct type *last;                                              \
00312         ast_rwlock_t lock;                                              \
00313 } name;                                                                 \
00314 static void  __attribute__((constructor)) __init_##name(void)          \
00315 {                                                                       \
00316         AST_RWDLLIST_HEAD_INIT(&name);                                    \
00317 }                                                                       \
00318 static void  __attribute__((destructor)) __fini_##name(void)           \
00319 {                                                                       \
00320         AST_RWDLLIST_HEAD_DESTROY(&name);                                 \
00321 }                                                                       \
00322 struct __dummy_##name
00323 #else
00324 #define AST_RWDLLIST_HEAD_STATIC(name, type)                              \
00325 struct name {                                                           \
00326         struct type *first;                                             \
00327         struct type *last;                                              \
00328         ast_rwlock_t lock;                                              \
00329 } name = AST_RWDLLIST_HEAD_INIT_VALUE
00330 #endif
00331 
00332 /*!
00333   \brief Defines a structure to be used to hold a list of specified type, statically initialized.
00334 
00335   This is the same as AST_DLLIST_HEAD_STATIC, except without the lock included.
00336   \since 1.6.1
00337 */
00338 #define AST_DLLIST_HEAD_NOLOCK_STATIC(name, type)           \
00339 struct name {                       \
00340    struct type *first;                 \
00341    struct type *last;                  \
00342 } name = AST_DLLIST_HEAD_NOLOCK_INIT_VALUE
00343 
00344 /*!
00345   \brief Initializes a list head structure with a specified first entry.
00346   \param head This is a pointer to the list head structure
00347   \param entry pointer to the list entry that will become the head of the list
00348 
00349   This macro initializes a list head structure by setting the head
00350   entry to the supplied value and recreating the embedded lock.
00351   \since 1.6.1
00352 */
00353 #define AST_DLLIST_HEAD_SET(head, entry) do {            \
00354    (head)->first = (entry);               \
00355    (head)->last = (entry);                \
00356    ast_mutex_init(&(head)->lock);               \
00357 } while (0)
00358 
00359 /*!
00360   \brief Initializes an rwlist head structure with a specified first entry.
00361   \param head This is a pointer to the list head structure
00362   \param entry pointer to the list entry that will become the head of the list
00363 
00364   This macro initializes a list head structure by setting the head
00365   entry to the supplied value and recreating the embedded lock.
00366   \since 1.6.1
00367 */
00368 #define AST_RWDLLIST_HEAD_SET(head, entry) do {                           \
00369         (head)->first = (entry);                                        \
00370         (head)->last = (entry);                                         \
00371         ast_rwlock_init(&(head)->lock);                                 \
00372 } while (0)
00373 
00374 /*!
00375   \brief Initializes a list head structure with a specified first entry.
00376   \param head This is a pointer to the list head structure
00377   \param entry pointer to the list entry that will become the head of the list
00378 
00379   This macro initializes a list head structure by setting the head
00380   entry to the supplied value.
00381   \since 1.6.1
00382 */
00383 #define AST_DLLIST_HEAD_SET_NOLOCK(head, entry) do {        \
00384    (head)->first = (entry);               \
00385    (head)->last = (entry);                \
00386 } while (0)
00387 
00388 /*!
00389   \brief Declare previous/forward links inside a list entry.
00390   \param type This is the type of each list entry.
00391 
00392   This macro declares a structure to be used to doubly link list entries together.
00393   It must be used inside the definition of the structure named in
00394   \a type, as follows:
00395 
00396   \code
00397   struct list_entry {
00398    ...
00399    AST_DLLIST_ENTRY(list_entry) list;
00400   }
00401   \endcode
00402 
00403   The field name \a list here is arbitrary, and can be anything you wish.
00404   \since 1.6.1
00405 */
00406 #define AST_DLLIST_ENTRY(type)         \
00407 struct {                      \
00408    struct type *prev;                  \
00409    struct type *next;                  \
00410 }
00411 
00412 #define AST_RWDLLIST_ENTRY AST_DLLIST_ENTRY
00413 
00414 /*!
00415   \brief Returns the first entry contained in a list.
00416   \param head This is a pointer to the list head structure
00417   \since 1.6.1
00418  */
00419 #define  AST_DLLIST_FIRST(head)  ((head)->first)
00420 
00421 #define AST_RWDLLIST_FIRST AST_DLLIST_FIRST
00422 
00423 /*!
00424   \brief Returns the last entry contained in a list.
00425   \param head This is a pointer to the list head structure
00426   \since 1.6.1
00427  */
00428 #define  AST_DLLIST_LAST(head)   ((head)->last)
00429 
00430 #define AST_RWDLLIST_LAST AST_DLLIST_LAST
00431 
00432 /*!
00433   \brief Returns the next entry in the list after the given entry.
00434   \param elm This is a pointer to the current entry.
00435   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00436   used to link entries of this list together.
00437   \since 1.6.1
00438 */
00439 #define AST_DLLIST_NEXT(elm, field) ((elm)->field.next)
00440 
00441 #define AST_RWDLLIST_NEXT AST_DLLIST_NEXT
00442 
00443 /*!
00444   \brief Returns the previous entry in the list before the given entry.
00445   \param elm This is a pointer to the current entry.
00446   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00447   used to link entries of this list together.
00448   \since 1.6.1
00449 */
00450 #define AST_DLLIST_PREV(elm, field) ((elm)->field.prev)
00451 
00452 #define AST_RWDLLIST_PREV AST_DLLIST_PREV
00453 
00454 /*!
00455   \brief Checks whether the specified list contains any entries.
00456   \param head This is a pointer to the list head structure
00457 
00458   \return non-zero if the list has entries
00459   \return zero if not.
00460   \since 1.6.1
00461  */
00462 #define  AST_DLLIST_EMPTY(head)  (AST_DLLIST_FIRST(head) == NULL)
00463 
00464 #define AST_RWDLLIST_EMPTY AST_DLLIST_EMPTY
00465 
00466 /*!
00467   \brief Loops over (traverses) the entries in a list.
00468   \param head This is a pointer to the list head structure
00469   \param var This is the name of the variable that will hold a pointer to the
00470   current list entry on each iteration. It must be declared before calling
00471   this macro.
00472   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00473   used to link entries of this list together.
00474 
00475   This macro is use to loop over (traverse) the entries in a list. It uses a
00476   \a for loop, and supplies the enclosed code with a pointer to each list
00477   entry as it loops. It is typically used as follows:
00478   \code
00479   static AST_DLLIST_HEAD(entry_list, list_entry) entries;
00480   ...
00481   struct list_entry {
00482    ...
00483    AST_DLLIST_ENTRY(list_entry) list;
00484   }
00485   ...
00486   struct list_entry *current;
00487   ...
00488   AST_DLLIST_TRAVERSE(&entries, current, list) {
00489      (do something with current here)
00490   }
00491   \endcode
00492   \warning If you modify the forward-link pointer contained in the \a current entry while
00493   inside the loop, the behavior will be unpredictable. At a minimum, the following
00494   macros will modify the forward-link pointer, and should not be used inside
00495   AST_DLLIST_TRAVERSE() against the entry pointed to by the \a current pointer without
00496   careful consideration of their consequences:
00497   \li AST_DLLIST_NEXT() (when used as an lvalue)
00498   \li AST_DLLIST_INSERT_AFTER()
00499   \li AST_DLLIST_INSERT_HEAD()
00500   \li AST_DLLIST_INSERT_TAIL()
00501   \since 1.6.1
00502 */
00503 #define AST_DLLIST_TRAVERSE(head,var,field)           \
00504    for((var) = (head)->first; (var); (var) = (var)->field.next)
00505 
00506 #define AST_RWDLLIST_TRAVERSE AST_DLLIST_TRAVERSE
00507 
00508 /*!
00509   \brief Loops over (traverses) the entries in a list in reverse order, starting at the end.
00510   \param head This is a pointer to the list head structure
00511   \param var This is the name of the variable that will hold a pointer to the
00512   current list entry on each iteration. It must be declared before calling
00513   this macro.
00514   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00515   used to link entries of this list together.
00516 
00517   This macro is use to loop over (traverse) the entries in a list in reverse order. It uses a
00518   \a for loop, and supplies the enclosed code with a pointer to each list
00519   entry as it loops. It is typically used as follows:
00520   \code
00521   static AST_DLLIST_HEAD(entry_list, list_entry) entries;
00522   ...
00523   struct list_entry {
00524    ...
00525    AST_DLLIST_ENTRY(list_entry) list;
00526   }
00527   ...
00528   struct list_entry *current;
00529   ...
00530   AST_DLLIST_TRAVERSE_BACKWARDS(&entries, current, list) {
00531      (do something with current here)
00532   }
00533   \endcode
00534   \warning If you modify the forward-link pointer contained in the \a current entry while
00535   inside the loop, the behavior will be unpredictable. At a minimum, the following
00536   macros will modify the forward-link pointer, and should not be used inside
00537   AST_DLLIST_TRAVERSE() against the entry pointed to by the \a current pointer without
00538   careful consideration of their consequences:
00539   \li AST_DLLIST_PREV() (when used as an lvalue)
00540   \li AST_DLLIST_INSERT_BEFORE()
00541   \li AST_DLLIST_INSERT_HEAD()
00542   \li AST_DLLIST_INSERT_TAIL()
00543   \since 1.6.1
00544 */
00545 #define AST_DLLIST_TRAVERSE_BACKWARDS(head,var,field)             \
00546    for((var) = (head)->last; (var); (var) = (var)->field.prev)
00547 
00548 #define AST_RWDLLIST_TRAVERSE_BACKWARDS AST_DLLIST_TRAVERSE_BACKWARDS
00549 
00550 /*!
00551   \brief Loops safely over (traverses) the entries in a list.
00552   \param head This is a pointer to the list head structure
00553   \param var This is the name of the variable that will hold a pointer to the
00554   current list entry on each iteration. It must be declared before calling
00555   this macro.
00556   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00557   used to link entries of this list together.
00558 
00559   This macro is used to safely loop over (traverse) the entries in a list. It
00560   uses a \a for loop, and supplies the enclosed code with a pointer to each list
00561   entry as it loops. It is typically used as follows:
00562 
00563   \code
00564   static AST_DLLIST_HEAD(entry_list, list_entry) entries;
00565   ...
00566   struct list_entry {
00567    ...
00568    AST_DLLIST_ENTRY(list_entry) list;
00569   }
00570   ...
00571   struct list_entry *current;
00572   ...
00573   AST_DLLIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
00574      (do something with current here)
00575   }
00576   AST_DLLIST_TRAVERSE_SAFE_END;
00577   \endcode
00578 
00579   It differs from AST_DLLIST_TRAVERSE() in that the code inside the loop can modify
00580   (or even free, after calling AST_DLLIST_REMOVE_CURRENT()) the entry pointed to by
00581   the \a current pointer without affecting the loop traversal.
00582   \since 1.6.1
00583 */
00584 #define AST_DLLIST_TRAVERSE_SAFE_BEGIN(head, var, field) {           \
00585    typeof((head)) __list_head = head;                 \
00586    typeof(__list_head->first) __list_next;                  \
00587    typeof(__list_head->first) __list_prev = NULL;              \
00588    typeof(__list_head->first) __new_prev = NULL;               \
00589    for ((var) = __list_head->first, __new_prev = (var),           \
00590          __list_next = (var) ? (var)->field.next : NULL;          \
00591         (var);                         \
00592         __list_prev = __new_prev, (var) = __list_next,            \
00593         __new_prev = (var),                     \
00594         __list_next = (var) ? (var)->field.next : NULL            \
00595        )
00596 
00597 #define AST_RWDLLIST_TRAVERSE_SAFE_BEGIN AST_DLLIST_TRAVERSE_SAFE_BEGIN
00598 
00599 /*!
00600   \brief Loops safely over (traverses) the entries in a list.
00601   \param head This is a pointer to the list head structure
00602   \param var This is the name of the variable that will hold a pointer to the
00603   current list entry on each iteration. It must be declared before calling
00604   this macro.
00605   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00606   used to link entries of this list together.
00607 
00608   This macro is used to safely loop over (traverse) the entries in a list. It
00609   uses a \a for loop, and supplies the enclosed code with a pointer to each list
00610   entry as it loops. It is typically used as follows:
00611 
00612   \code
00613   static AST_DLLIST_HEAD(entry_list, list_entry) entries;
00614   ...
00615   struct list_entry {
00616    ...
00617    AST_DLLIST_ENTRY(list_entry) list;
00618   }
00619   ...
00620   struct list_entry *current;
00621   ...
00622   AST_DLLIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
00623      (do something with current here)
00624   }
00625   AST_DLLIST_TRAVERSE_SAFE_END;
00626   \endcode
00627 
00628   It differs from AST_DLLIST_TRAVERSE() in that the code inside the loop can modify
00629   (or even free, after calling AST_DLLIST_REMOVE_CURRENT()) the entry pointed to by
00630   the \a current pointer without affecting the loop traversal.
00631   \since 1.6.1
00632 */
00633 #define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(head, var, field) {          \
00634    typeof((head)) __list_head = head;                 \
00635    typeof(__list_head->first) __list_next;                  \
00636    typeof(__list_head->first) __list_prev = NULL;              \
00637    typeof(__list_head->first) __new_prev = NULL;               \
00638    for ((var) = __list_head->last, __new_prev = (var),            \
00639           __list_next = NULL, __list_prev = (var) ? (var)->field.prev : NULL; \
00640         (var);                         \
00641         __list_next = __new_prev, (var) = __list_prev,            \
00642         __new_prev = (var),                     \
00643         __list_prev = (var) ? (var)->field.prev : NULL            \
00644        )
00645 
00646 #define AST_RWDLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN
00647 
00648 /*!
00649   \brief Removes the \a current entry from a list during a traversal.
00650   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00651   used to link entries of this list together.
00652 
00653   \note This macro can \b only be used inside an AST_DLLIST_TRAVERSE_SAFE_BEGIN()
00654   block; it is used to unlink the current entry from the list without affecting
00655   the list traversal (and without having to re-traverse the list to modify the
00656   previous entry, if any).
00657   \since 1.6.1
00658  */
00659 #define AST_DLLIST_REMOVE_CURRENT(field) do {         \
00660    __new_prev->field.next = NULL;                  \
00661    __new_prev->field.prev = NULL;                  \
00662    if (__list_next)                          \
00663       __new_prev = __list_prev;                 \
00664    else                                   \
00665       __new_prev = NULL;                        \
00666    if (__list_prev) {                                  \
00667       if (__list_next)                       \
00668          __list_next->field.prev = __list_prev;    \
00669       __list_prev->field.next = __list_next;       \
00670    } else {                                            \
00671       __list_head->first = __list_next;            \
00672       if (__list_next)                       \
00673          __list_next->field.prev = NULL;           \
00674    }                                      \
00675    if (!__list_next)                         \
00676       __list_head->last = __list_prev;             \
00677    } while (0)
00678 
00679 #define AST_RWDLLIST_REMOVE_CURRENT AST_DLLIST_REMOVE_CURRENT
00680 
00681 #define AST_DLLIST_MOVE_CURRENT(newhead, field) do { \
00682    typeof ((newhead)->first) __list_cur = __new_prev;          \
00683    AST_DLLIST_REMOVE_CURRENT(field);                     \
00684    AST_DLLIST_INSERT_TAIL((newhead), __list_cur, field);          \
00685    } while (0)
00686 
00687 #define AST_RWDLLIST_MOVE_CURRENT AST_DLLIST_MOVE_CURRENT
00688 
00689 #define AST_DLLIST_MOVE_CURRENT_BACKWARDS(newhead, field) do { \
00690    typeof ((newhead)->first) __list_cur = __new_prev;       \
00691    if (!__list_next) {                                \
00692       AST_DLLIST_REMOVE_CURRENT(field);                  \
00693       __new_prev = NULL;                              \
00694       AST_DLLIST_INSERT_HEAD((newhead), __list_cur, field); \
00695    } else {                                     \
00696       AST_DLLIST_REMOVE_CURRENT(field);                  \
00697       AST_DLLIST_INSERT_HEAD((newhead), __list_cur, field); \
00698    }} while (0)
00699 
00700 #define AST_RWDLLIST_MOVE_CURRENT_BACKWARDS AST_DLLIST_MOVE_CURRENT
00701 
00702 /*!
00703   \brief Inserts a list entry before the current entry during a traversal.
00704   \param elm This is a pointer to the entry to be inserted.
00705   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00706   used to link entries of this list together.
00707 
00708   \note This macro can \b only be used inside an AST_DLLIST_TRAVERSE_SAFE_BEGIN()
00709   block.
00710   \since 1.6.1
00711  */
00712 #define AST_DLLIST_INSERT_BEFORE_CURRENT(elm, field) do {   \
00713    if (__list_prev) {                              \
00714       (elm)->field.next = __list_prev->field.next;    \
00715       (elm)->field.prev = __list_prev;             \
00716       if (__list_prev->field.next)                        \
00717          __list_prev->field.next->field.prev = (elm); \
00718       __list_prev->field.next = (elm);             \
00719    } else {                                  \
00720       (elm)->field.next = __list_head->first;         \
00721       __list_head->first->field.prev = (elm);         \
00722       (elm)->field.prev = NULL;                 \
00723       __list_head->first = (elm);                  \
00724    }                                      \
00725 } while (0)
00726 
00727 #define AST_RWDLLIST_INSERT_BEFORE_CURRENT AST_DLLIST_INSERT_BEFORE_CURRENT
00728 
00729 /*!
00730   \brief Inserts a list entry after the current entry during a backwards traversal. Since
00731          this is a backwards traversal, this will insert the entry AFTER the current
00732          element. Since this is a backwards traveral, though, this would be BEFORE
00733          the current entry in traversal order. Confusing?
00734   \param elm This is a pointer to the entry to be inserted.
00735   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00736   used to link entries of this list together.
00737 
00738   \note This macro can \b only be used inside an AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN()
00739   block. If you use this with the AST_DLLIST_TRAVERSE_SAFE_BEGIN(), be prepared for
00740   strange things!
00741   \since 1.6.1
00742  */
00743 #define AST_DLLIST_INSERT_BEFORE_CURRENT_BACKWARDS(elm, field) do {        \
00744    if (__list_next) {                        \
00745       (elm)->field.next = __list_next;       \
00746       (elm)->field.prev = __new_prev;           \
00747       __new_prev->field.next = (elm);              \
00748       __list_next->field.prev = (elm);          \
00749    } else {                            \
00750       (elm)->field.prev = __list_head->last;    \
00751       (elm)->field.next = NULL;              \
00752       __list_head->last->field.next = (elm);    \
00753       __list_head->last = (elm);             \
00754    }                                   \
00755 } while (0)
00756 
00757 #define AST_RWDLLIST_INSERT_BEFORE_CURRENT_BACKWARDS AST_DLLIST_INSERT_BEFORE_CURRENT_BACKWARDS
00758 
00759 /*!
00760   \brief Closes a safe loop traversal block.
00761   \since 1.6.1
00762  */
00763 #define AST_DLLIST_TRAVERSE_SAFE_END  }
00764 
00765 #define AST_RWDLLIST_TRAVERSE_SAFE_END AST_DLLIST_TRAVERSE_SAFE_END
00766 
00767 /*!
00768   \brief Closes a safe loop traversal block.
00769   \since 1.6.1
00770  */
00771 #define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END  }
00772 
00773 #define AST_RWDLLIST_TRAVERSE_BACKWARDS_SAFE_END AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END
00774 
00775 /*!
00776   \brief Initializes a list head structure.
00777   \param head This is a pointer to the list head structure
00778 
00779   This macro initializes a list head structure by setting the head
00780   entry to \a NULL (empty list) and recreating the embedded lock.
00781   \since 1.6.1
00782 */
00783 #define AST_DLLIST_HEAD_INIT(head) {               \
00784    (head)->first = NULL;                  \
00785    (head)->last = NULL;                \
00786    ast_mutex_init(&(head)->lock);               \
00787 }
00788 
00789 /*!
00790   \brief Initializes an rwlist head structure.
00791   \param head This is a pointer to the list head structure
00792 
00793   This macro initializes a list head structure by setting the head
00794   entry to \a NULL (empty list) and recreating the embedded lock.
00795   \since 1.6.1
00796 */
00797 #define AST_RWDLLIST_HEAD_INIT(head) {                                    \
00798         (head)->first = NULL;                                           \
00799         (head)->last = NULL;                                            \
00800         ast_rwlock_init(&(head)->lock);                                 \
00801 }
00802 
00803 /*!
00804   \brief Destroys a list head structure.
00805   \param head This is a pointer to the list head structure
00806 
00807   This macro destroys a list head structure by setting the head
00808   entry to \a NULL (empty list) and destroying the embedded lock.
00809   It does not free the structure from memory.
00810   \since 1.6.1
00811 */
00812 #define AST_DLLIST_HEAD_DESTROY(head) {               \
00813    (head)->first = NULL;                  \
00814    (head)->last = NULL;                \
00815    ast_mutex_destroy(&(head)->lock);            \
00816 }
00817 
00818 /*!
00819   \brief Destroys an rwlist head structure.
00820   \param head This is a pointer to the list head structure
00821 
00822   This macro destroys a list head structure by setting the head
00823   entry to \a NULL (empty list) and destroying the embedded lock.
00824   It does not free the structure from memory.
00825   \since 1.6.1
00826 */
00827 #define AST_RWDLLIST_HEAD_DESTROY(head) {                                 \
00828         (head)->first = NULL;                                           \
00829         (head)->last = NULL;                                            \
00830         ast_rwlock_destroy(&(head)->lock);                              \
00831 }
00832 
00833 /*!
00834   \brief Initializes a list head structure.
00835   \param head This is a pointer to the list head structure
00836 
00837   This macro initializes a list head structure by setting the head
00838   entry to \a NULL (empty list). There is no embedded lock handling
00839   with this macro.
00840   \since 1.6.1
00841 */
00842 #define AST_DLLIST_HEAD_INIT_NOLOCK(head) {           \
00843    (head)->first = NULL;                  \
00844    (head)->last = NULL;                \
00845 }
00846 
00847 /*!
00848   \brief Inserts a list entry after a given entry.
00849   \param head This is a pointer to the list head structure
00850   \param listelm This is a pointer to the entry after which the new entry should
00851   be inserted.
00852   \param elm This is a pointer to the entry to be inserted.
00853   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00854   used to link entries of this list together.
00855   \since 1.6.1
00856  */
00857 #define AST_DLLIST_INSERT_AFTER(head, listelm, elm, field) do {      \
00858    (elm)->field.next = (listelm)->field.next;         \
00859    (elm)->field.prev = (listelm);         \
00860    if ((listelm)->field.next)          \
00861       (listelm)->field.next->field.prev = (elm);   \
00862    (listelm)->field.next = (elm);               \
00863    if ((head)->last == (listelm))               \
00864       (head)->last = (elm);               \
00865 } while (0)
00866 
00867 #define AST_RWDLLIST_INSERT_AFTER AST_DLLIST_INSERT_AFTER
00868 
00869 /*!
00870   \brief Inserts a list entry before a given entry.
00871   \param head This is a pointer to the list head structure
00872   \param listelm This is a pointer to the entry before which the new entry should
00873   be inserted.
00874   \param elm This is a pointer to the entry to be inserted.
00875   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00876   used to link entries of this list together.
00877   \since 1.6.1
00878  */
00879 #define AST_DLLIST_INSERT_BEFORE(head, listelm, elm, field) do {     \
00880    (elm)->field.next = (listelm);         \
00881    (elm)->field.prev = (listelm)->field.prev;         \
00882    if ((listelm)->field.prev)          \
00883       (listelm)->field.prev->field.next = (elm);   \
00884    (listelm)->field.prev = (elm);               \
00885    if ((head)->first == (listelm))              \
00886       (head)->first = (elm);              \
00887 } while (0)
00888 
00889 #define AST_RWDLLIST_INSERT_BEFORE AST_DLLIST_INSERT_BEFORE
00890 
00891 /*!
00892   \brief Inserts a list entry at the head of a list.
00893   \param head This is a pointer to the list head structure
00894   \param elm This is a pointer to the entry to be inserted.
00895   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00896   used to link entries of this list together.
00897   \since 1.6.1
00898  */
00899 #define AST_DLLIST_INSERT_HEAD(head, elm, field) do {       \
00900       (elm)->field.next = (head)->first;        \
00901       if ((head)->first)                          \
00902          (head)->first->field.prev = (elm);        \
00903       (elm)->field.prev = NULL;        \
00904       (head)->first = (elm);              \
00905       if (!(head)->last)               \
00906          (head)->last = (elm);            \
00907 } while (0)
00908 
00909 #define AST_RWDLLIST_INSERT_HEAD AST_DLLIST_INSERT_HEAD
00910 
00911 /*!
00912   \brief Appends a list entry to the tail of a list.
00913   \param head This is a pointer to the list head structure
00914   \param elm This is a pointer to the entry to be appended.
00915   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00916   used to link entries of this list together.
00917 
00918   Note: The link field in the appended entry is \b not modified, so if it is
00919   actually the head of a list itself, the entire list will be appended
00920   temporarily (until the next AST_DLLIST_INSERT_TAIL is performed).
00921   \since 1.6.1
00922  */
00923 #define AST_DLLIST_INSERT_TAIL(head, elm, field) do { \
00924       if (!(head)->first) {                  \
00925       (head)->first = (elm);              \
00926       (head)->last = (elm);                   \
00927       (elm)->field.next = NULL;           \
00928       (elm)->field.prev = NULL;           \
00929       } else {                         \
00930       (head)->last->field.next = (elm);      \
00931       (elm)->field.prev = (head)->last;      \
00932       (elm)->field.next = NULL;           \
00933       (head)->last = (elm);               \
00934       }                                \
00935 } while (0)
00936 
00937 #define AST_RWDLLIST_INSERT_TAIL AST_DLLIST_INSERT_TAIL
00938 
00939 /*!
00940   \brief Appends a whole list to the tail of a list.
00941   \param head This is a pointer to the list head structure
00942   \param list This is a pointer to the list to be appended.
00943   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00944   used to link entries of this list together.
00945 
00946   Note: The source list (the \a list parameter) will be empty after
00947   calling this macro (the list entries are \b moved to the target list).
00948   \since 1.6.1
00949  */
00950 #define AST_DLLIST_APPEND_DLLIST(head, list, field) do {       \
00951       if (!(head)->first) {                  \
00952       (head)->first = (list)->first;            \
00953       (head)->last = (list)->last;           \
00954       } else {                      \
00955       (head)->last->field.next = (list)->first;    \
00956       (list)->first->field.prev = (head)->last;    \
00957       (head)->last = (list)->last;           \
00958       }                          \
00959       (list)->first = NULL;                  \
00960       (list)->last = NULL;                \
00961 } while (0)
00962 
00963 #define AST_RWDLLIST_APPEND_DLLIST AST_DLLIST_APPEND_DLLIST
00964 
00965 /*!
00966   \brief Removes and returns the head entry from a list.
00967   \param head This is a pointer to the list head structure
00968   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00969   used to link entries of this list together.
00970 
00971   Removes the head entry from the list, and returns a pointer to it.
00972   This macro is safe to call on an empty list.
00973   \since 1.6.1
00974  */
00975 #define AST_DLLIST_REMOVE_HEAD(head, field) ({           \
00976       typeof((head)->first) cur = (head)->first;      \
00977       if (cur) {                 \
00978          (head)->first = cur->field.next;    \
00979          if (cur->field.next)                \
00980             cur->field.next->field.prev = NULL; \
00981          cur->field.next = NULL;          \
00982          if ((head)->last == cur)         \
00983             (head)->last = NULL;       \
00984       }                    \
00985       cur;                    \
00986    })
00987 
00988 #define AST_RWDLLIST_REMOVE_HEAD AST_DLLIST_REMOVE_HEAD
00989 
00990 /*!
00991   \brief Removes a specific entry from a list.
00992   \param head This is a pointer to the list head structure
00993   \param elm This is a pointer to the entry to be removed.
00994   \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
00995   used to link entries of this list together.
00996   \warning The removed entry is \b not freed nor modified in any way.
00997   \since 1.6.1
00998  */
00999 #define AST_DLLIST_REMOVE(head, elm, field) ({                \
01000    __typeof(elm) __res = (elm);                 \
01001    if ((head)->first == (elm)) {                      \
01002       (head)->first = (elm)->field.next;                 \
01003       if ((elm)->field.next)                          \
01004          (elm)->field.next->field.prev = NULL;           \
01005       if ((head)->last == (elm))                      \
01006          (head)->last = NULL;                      \
01007    } else {                                        \
01008       (elm)->field.prev->field.next = (elm)->field.next;       \
01009       if ((elm)->field.next)                                \
01010          (elm)->field.next->field.prev = (elm)->field.prev;       \
01011       if ((head)->last == (elm))                            \
01012          (head)->last = (elm)->field.prev;                     \
01013    }                                                  \
01014    (elm)->field.next = NULL;                                \
01015    (elm)->field.prev = NULL;                                \
01016    (__res);                                           \
01017 })
01018 
01019 #define AST_RWDLLIST_REMOVE AST_DLLIST_REMOVE
01020 
01021 #endif /* _ASTERISK_DLINKEDLISTS_H */

Generated on Mon Jun 27 16:50:53 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7