dlinkedlists.h 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2007, Digium, Inc.
  5. *
  6. * Steve Murphy <murf@digium.com>
  7. *
  8. * Doubly-Linked List Macros--
  9. * Based on linkedlists.h (to the point of plagiarism!), which is by:
  10. *
  11. * Mark Spencer <markster@digium.com>
  12. * Kevin P. Fleming <kpfleming@digium.com>
  13. *
  14. * See http://www.asterisk.org for more information about
  15. * the Asterisk project. Please do not directly contact
  16. * any of the maintainers of this project for assistance;
  17. * the project provides a web site, mailing lists and IRC
  18. * channels for your use.
  19. *
  20. * This program is free software, distributed under the terms of
  21. * the GNU General Public License Version 2. See the LICENSE file
  22. * at the top of the source tree.
  23. */
  24. #ifndef ASTERISK_DLINKEDLISTS_H
  25. #define ASTERISK_DLINKEDLISTS_H
  26. #include "asterisk/lock.h"
  27. /*!
  28. * \file dlinkedlists.h
  29. * \brief A set of macros to manage doubly-linked lists.
  30. */
  31. /*!
  32. * \brief Locks a list.
  33. * \param head This is a pointer to the list head structure
  34. *
  35. * This macro attempts to place an exclusive lock in the
  36. * list head structure pointed to by head.
  37. * \retval 0 on success
  38. * \retval non-zero on failure
  39. * \since 1.6.1
  40. */
  41. #define AST_DLLIST_LOCK(head) \
  42. ast_mutex_lock(&(head)->lock)
  43. /*!
  44. * \brief Write locks a list.
  45. * \param head This is a pointer to the list head structure
  46. *
  47. * This macro attempts to place an exclusive write lock in the
  48. * list head structure pointed to by head.
  49. * \retval 0 on success
  50. * \retval non-zero on failure
  51. * \since 1.6.1
  52. */
  53. #define AST_RWDLLIST_WRLOCK(head) \
  54. ast_rwlock_wrlock(&(head)->lock)
  55. /*!
  56. * \brief Read locks a list.
  57. * \param head This is a pointer to the list head structure
  58. *
  59. * This macro attempts to place a read lock in the
  60. * list head structure pointed to by head.
  61. * \retval 0 on success
  62. * \retval non-zero on failure
  63. * \since 1.6.1
  64. */
  65. #define AST_RWDLLIST_RDLOCK(head) \
  66. ast_rwlock_rdlock(&(head)->lock)
  67. /*!
  68. * \brief Locks a list, without blocking if the list is locked.
  69. * \param head This is a pointer to the list head structure
  70. *
  71. * This macro attempts to place an exclusive lock in the
  72. * list head structure pointed to by head.
  73. * \retval 0 on success
  74. * \retval non-zero on failure
  75. * \since 1.6.1
  76. */
  77. #define AST_DLLIST_TRYLOCK(head) \
  78. ast_mutex_trylock(&(head)->lock)
  79. /*!
  80. * \brief Write locks a list, without blocking if the list is locked.
  81. * \param head This is a pointer to the list head structure
  82. *
  83. * This macro attempts to place an exclusive write lock in the
  84. * list head structure pointed to by head.
  85. * \retval 0 on success
  86. * \retval non-zero on failure
  87. * \since 1.6.1
  88. */
  89. #define AST_RWDLLIST_TRYWRLOCK(head) \
  90. ast_rwlock_trywrlock(&(head)->lock)
  91. /*!
  92. * \brief Read locks a list, without blocking if the list is locked.
  93. * \param head This is a pointer to the list head structure
  94. *
  95. * This macro attempts to place a read lock in the
  96. * list head structure pointed to by head.
  97. * \retval 0 on success
  98. * \retval non-zero on failure
  99. * \since 1.6.1
  100. */
  101. #define AST_RWDLLIST_TRYRDLOCK(head) \
  102. ast_rwlock_tryrdlock(&(head)->lock)
  103. /*!
  104. * \brief Attempts to unlock a list.
  105. * \param head This is a pointer to the list head structure
  106. *
  107. * This macro attempts to remove an exclusive lock from the
  108. * list head structure pointed to by head. If the list
  109. * was not locked by this thread, this macro has no effect.
  110. * \since 1.6.1
  111. */
  112. #define AST_DLLIST_UNLOCK(head) \
  113. ast_mutex_unlock(&(head)->lock)
  114. /*!
  115. * \brief Attempts to unlock a read/write based list.
  116. * \param head This is a pointer to the list head structure
  117. *
  118. * This macro attempts to remove a read or write lock from the
  119. * list head structure pointed to by head. If the list
  120. * was not locked by this thread, this macro has no effect.
  121. * \since 1.6.1
  122. */
  123. #define AST_RWDLLIST_UNLOCK(head) \
  124. ast_rwlock_unlock(&(head)->lock)
  125. /*!
  126. * \brief Defines a structure to be used to hold a list of specified type.
  127. * \param name This will be the name of the defined structure.
  128. * \param type This is the type of each list entry.
  129. *
  130. * This macro creates a structure definition that can be used
  131. * to hold a list of the entries of type \a type. It does not actually
  132. * declare (allocate) a structure; to do that, either follow this
  133. * macro with the desired name of the instance you wish to declare,
  134. * or use the specified \a name to declare instances elsewhere.
  135. *
  136. * Example usage:
  137. * \code
  138. * static AST_DLLIST_HEAD(entry_list, entry) entries;
  139. * \endcode
  140. *
  141. * This would define \c struct \c entry_list, and declare an instance of it named
  142. * \a entries, all intended to hold a list of type \c struct \c entry.
  143. * \since 1.6.1
  144. */
  145. #define AST_DLLIST_HEAD(name, type) \
  146. struct name { \
  147. struct type *first; \
  148. struct type *last; \
  149. ast_mutex_t lock; \
  150. }
  151. /*!
  152. * \brief Defines a structure to be used to hold a read/write list of specified type.
  153. * \param name This will be the name of the defined structure.
  154. * \param type This is the type of each list entry.
  155. *
  156. * This macro creates a structure definition that can be used
  157. * to hold a list of the entries of type \a type. It does not actually
  158. * declare (allocate) a structure; to do that, either follow this
  159. * macro with the desired name of the instance you wish to declare,
  160. * or use the specified \a name to declare instances elsewhere.
  161. *
  162. * Example usage:
  163. * \code
  164. * static AST_RWDLLIST_HEAD(entry_list, entry) entries;
  165. * \endcode
  166. *
  167. * This would define \c struct \c entry_list, and declare an instance of it named
  168. * \a entries, all intended to hold a list of type \c struct \c entry.
  169. * \since 1.6.1
  170. */
  171. #define AST_RWDLLIST_HEAD(name, type) \
  172. struct name { \
  173. struct type *first; \
  174. struct type *last; \
  175. ast_rwlock_t lock; \
  176. }
  177. /*!
  178. * \brief Defines a structure to be used to hold a list of specified type (with no lock).
  179. * \param name This will be the name of the defined structure.
  180. * \param type This is the type of each list entry.
  181. *
  182. * This macro creates a structure definition that can be used
  183. * to hold a list of the entries of type \a type. It does not actually
  184. * declare (allocate) a structure; to do that, either follow this
  185. * macro with the desired name of the instance you wish to declare,
  186. * or use the specified \a name to declare instances elsewhere.
  187. *
  188. * Example usage:
  189. * \code
  190. * static AST_DLLIST_HEAD_NOLOCK(entry_list, entry) entries;
  191. * \endcode
  192. *
  193. * This would define \c struct \c entry_list, and declare an instance of it named
  194. * \a entries, all intended to hold a list of type \c struct \c entry.
  195. * \since 1.6.1
  196. */
  197. #define AST_DLLIST_HEAD_NOLOCK(name, type) \
  198. struct name { \
  199. struct type *first; \
  200. struct type *last; \
  201. }
  202. /*!
  203. * \brief Defines initial values for a declaration of AST_DLLIST_HEAD
  204. * \since 1.6.1
  205. */
  206. #define AST_DLLIST_HEAD_INIT_VALUE \
  207. { \
  208. .first = NULL, \
  209. .last = NULL, \
  210. .lock = AST_MUTEX_INIT_VALUE, \
  211. }
  212. /*!
  213. * \brief Defines initial values for a declaration of AST_RWDLLIST_HEAD
  214. * \since 1.6.1
  215. */
  216. #define AST_RWDLLIST_HEAD_INIT_VALUE \
  217. { \
  218. .first = NULL, \
  219. .last = NULL, \
  220. .lock = AST_RWLOCK_INIT_VALUE, \
  221. }
  222. /*!
  223. * \brief Defines initial values for a declaration of AST_DLLIST_HEAD_NOLOCK
  224. * \since 1.6.1
  225. */
  226. #define AST_DLLIST_HEAD_NOLOCK_INIT_VALUE \
  227. { \
  228. .first = NULL, \
  229. .last = NULL, \
  230. }
  231. /*!
  232. * \brief Defines a structure to be used to hold a list of specified type, statically initialized.
  233. * \param name This will be the name of the defined structure.
  234. * \param type This is the type of each list entry.
  235. *
  236. * This macro creates a structure definition that can be used
  237. * to hold a list of the entries of type \a type, and allocates an instance
  238. * of it, initialized to be empty.
  239. *
  240. * Example usage:
  241. * \code
  242. * static AST_DLLIST_HEAD_STATIC(entry_list, entry);
  243. * \endcode
  244. *
  245. * This would define \c struct \c entry_list, intended to hold a list of
  246. * type \c struct \c entry.
  247. * \since 1.6.1
  248. */
  249. #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
  250. #define AST_DLLIST_HEAD_STATIC(name, type) \
  251. struct name { \
  252. struct type *first; \
  253. struct type *last; \
  254. ast_mutex_t lock; \
  255. } name; \
  256. static void __attribute__((constructor)) __init_##name(void) \
  257. { \
  258. AST_DLLIST_HEAD_INIT(&name); \
  259. } \
  260. static void __attribute__((destructor)) __fini_##name(void) \
  261. { \
  262. AST_DLLIST_HEAD_DESTROY(&name); \
  263. } \
  264. struct __dummy_##name
  265. #else
  266. #define AST_DLLIST_HEAD_STATIC(name, type) \
  267. struct name { \
  268. struct type *first; \
  269. struct type *last; \
  270. ast_mutex_t lock; \
  271. } name = AST_DLLIST_HEAD_INIT_VALUE
  272. #endif
  273. /*!
  274. * \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
  275. * \param name This will be the name of the defined structure.
  276. * \param type This is the type of each list entry.
  277. *
  278. * This macro creates a structure definition that can be used
  279. * to hold a list of the entries of type \a type, and allocates an instance
  280. * of it, initialized to be empty.
  281. *
  282. * Example usage:
  283. * \code
  284. * static AST_RWDLLIST_HEAD_STATIC(entry_list, entry);
  285. * \endcode
  286. *
  287. * This would define \c struct \c entry_list, intended to hold a list of
  288. * type \c struct \c entry.
  289. * \since 1.6.1
  290. */
  291. #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
  292. #define AST_RWDLLIST_HEAD_STATIC(name, type) \
  293. struct name { \
  294. struct type *first; \
  295. struct type *last; \
  296. ast_rwlock_t lock; \
  297. } name; \
  298. static void __attribute__((constructor)) __init_##name(void) \
  299. { \
  300. AST_RWDLLIST_HEAD_INIT(&name); \
  301. } \
  302. static void __attribute__((destructor)) __fini_##name(void) \
  303. { \
  304. AST_RWDLLIST_HEAD_DESTROY(&name); \
  305. } \
  306. struct __dummy_##name
  307. #else
  308. #define AST_RWDLLIST_HEAD_STATIC(name, type) \
  309. struct name { \
  310. struct type *first; \
  311. struct type *last; \
  312. ast_rwlock_t lock; \
  313. } name = AST_RWDLLIST_HEAD_INIT_VALUE
  314. #endif
  315. /*!
  316. * \brief Defines a structure to be used to hold a list of specified type, statically initialized.
  317. *
  318. * This is the same as AST_DLLIST_HEAD_STATIC, except without the lock included.
  319. * \since 1.6.1
  320. */
  321. #define AST_DLLIST_HEAD_NOLOCK_STATIC(name, type) \
  322. struct name { \
  323. struct type *first; \
  324. struct type *last; \
  325. } name = AST_DLLIST_HEAD_NOLOCK_INIT_VALUE
  326. /*!
  327. * \brief Initializes a list head structure with a specified first entry.
  328. * \param head This is a pointer to the list head structure
  329. * \param entry pointer to the list entry that will become the head of the list
  330. *
  331. * This macro initializes a list head structure by setting the head
  332. * entry to the supplied value and recreating the embedded lock.
  333. * \since 1.6.1
  334. */
  335. #define AST_DLLIST_HEAD_SET(head, entry) \
  336. do { \
  337. (head)->first = (entry); \
  338. (head)->last = (entry); \
  339. ast_mutex_init(&(head)->lock); \
  340. } while (0)
  341. /*!
  342. * \brief Initializes an rwlist head structure with a specified first entry.
  343. * \param head This is a pointer to the list head structure
  344. * \param entry pointer to the list entry that will become the head of the list
  345. *
  346. * This macro initializes a list head structure by setting the head
  347. * entry to the supplied value and recreating the embedded lock.
  348. * \since 1.6.1
  349. */
  350. #define AST_RWDLLIST_HEAD_SET(head, entry) \
  351. do { \
  352. (head)->first = (entry); \
  353. (head)->last = (entry); \
  354. ast_rwlock_init(&(head)->lock); \
  355. } while (0)
  356. /*!
  357. * \brief Initializes a list head structure with a specified first entry.
  358. * \param head This is a pointer to the list head structure
  359. * \param entry pointer to the list entry that will become the head of the list
  360. *
  361. * This macro initializes a list head structure by setting the head
  362. * entry to the supplied value.
  363. * \since 1.6.1
  364. */
  365. #define AST_DLLIST_HEAD_SET_NOLOCK(head, entry) \
  366. do { \
  367. (head)->first = (entry); \
  368. (head)->last = (entry); \
  369. } while (0)
  370. /*!
  371. * \brief Declare previous/forward links inside a list entry.
  372. * \param type This is the type of each list entry.
  373. *
  374. * This macro declares a structure to be used to doubly link list entries together.
  375. * It must be used inside the definition of the structure named in
  376. * \a type, as follows:
  377. *
  378. * \code
  379. * struct list_entry {
  380. * ...
  381. * AST_DLLIST_ENTRY(list_entry) list;
  382. * }
  383. * \endcode
  384. *
  385. * The field name \a list here is arbitrary, and can be anything you wish.
  386. * \since 1.6.1
  387. */
  388. #define AST_DLLIST_ENTRY(type) AST_DLLIST_HEAD_NOLOCK(, type)
  389. #define AST_RWDLLIST_ENTRY AST_DLLIST_ENTRY
  390. /*!
  391. * \brief Returns the first entry contained in a list.
  392. * \param head This is a pointer to the list head structure
  393. * \since 1.6.1
  394. */
  395. #define AST_DLLIST_FIRST(head) ((head)->first)
  396. #define AST_RWDLLIST_FIRST AST_DLLIST_FIRST
  397. /*!
  398. * \brief Returns the last entry contained in a list.
  399. * \param head This is a pointer to the list head structure
  400. * \since 1.6.1
  401. */
  402. #define AST_DLLIST_LAST(head) ((head)->last)
  403. #define AST_RWDLLIST_LAST AST_DLLIST_LAST
  404. #define AST_DLLIST_NEXT_DIRECTION(elm, field, direction) ((elm)->field.direction)
  405. #define AST_RWDLLIST_NEXT_DIRECTION AST_DLLIST_NEXT_DIRECTION
  406. /*!
  407. * \brief Returns the next entry in the list after the given entry.
  408. * \param elm This is a pointer to the current entry.
  409. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  410. * used to link entries of this list together.
  411. * \since 1.6.1
  412. */
  413. #define AST_DLLIST_NEXT(elm, field) AST_DLLIST_NEXT_DIRECTION(elm, field, first)
  414. #define AST_RWDLLIST_NEXT AST_DLLIST_NEXT
  415. /*!
  416. * \brief Returns the previous entry in the list before the given entry.
  417. * \param elm This is a pointer to the current entry.
  418. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  419. * used to link entries of this list together.
  420. * \since 1.6.1
  421. */
  422. #define AST_DLLIST_PREV(elm, field) AST_DLLIST_NEXT_DIRECTION(elm, field, last)
  423. #define AST_RWDLLIST_PREV AST_DLLIST_PREV
  424. /*!
  425. * \brief Checks whether the specified list contains any entries.
  426. * \param head This is a pointer to the list head structure
  427. *
  428. * \return non-zero if the list has entries
  429. * \return zero if not.
  430. * \since 1.6.1
  431. */
  432. #define AST_DLLIST_EMPTY(head) (AST_DLLIST_FIRST(head) == NULL)
  433. #define AST_RWDLLIST_EMPTY AST_DLLIST_EMPTY
  434. /*!
  435. * \brief Checks whether the specified list contains the element.
  436. * \param head This is a pointer to the list head structure
  437. * \param elm This is a pointer to the list element to see if in list.
  438. * \param field List node field for the next node information.
  439. *
  440. * \return elm if the list has elm in it.
  441. * \return NULL if not.
  442. * \since 11
  443. */
  444. #define AST_DLLIST_IS_MEMBER(head, elm, field) \
  445. ({ \
  446. typeof((head)->first) __cur; \
  447. typeof((elm)) __elm = (elm); \
  448. if (!__elm) { \
  449. __cur = NULL; \
  450. } else { \
  451. __cur = (head)->first; \
  452. while (__cur && __cur != __elm) { \
  453. __cur = __cur->field.first; \
  454. } \
  455. } \
  456. __cur; \
  457. })
  458. #define AST_RWDLLIST_IS_MEMBER AST_DLLIST_IS_MEMBER
  459. /*!
  460. * \brief Traverse a doublly linked list using the specified direction list.
  461. *
  462. * \param head List head structure pointer.
  463. * \param var This is the name of the variable that will hold a pointer to the
  464. * current list node on each iteration. It must be declared before calling
  465. * this macro.
  466. * \param field List node field for the next node information. (declared using AST_DLLIST_ENTRY())
  467. * \param start Specified list node to start traversal: first or last
  468. *
  469. * This macro is use to loop over (traverse) the nodes in a list. It uses a
  470. * \a for loop, and supplies the enclosed code with a pointer to each list
  471. * node as it loops. It is typically used as follows:
  472. * \code
  473. * static AST_DLLIST_HEAD(entry_list, list_entry) entries;
  474. * ...
  475. * struct list_entry {
  476. * ...
  477. * AST_DLLIST_ENTRY(list_entry) list;
  478. * }
  479. * ...
  480. * struct list_entry *current;
  481. * ...
  482. * AST_DLLIST_TRAVERSE_DIRECTION(&entries, current, list, first) {
  483. * (do something with current here (travers list in forward direction))
  484. * }
  485. * ...
  486. * AST_DLLIST_TRAVERSE_DIRECTION(&entries, current, list, last) {
  487. * (do something with current here (travers list in reverse direction))
  488. * }
  489. * \endcode
  490. *
  491. * \since 11
  492. */
  493. #define AST_DLLIST_TRAVERSE_DIRECTION(head, var, field, start) \
  494. for ((var) = (head)->start; (var); (var) = AST_DLLIST_NEXT_DIRECTION(var, field, start))
  495. #define AST_RWDLLIST_TRAVERSE_DIRECTION AST_DLLIST_TRAVERSE_DIRECTION
  496. /*!
  497. * \brief Loops over (traverses) the entries in a list.
  498. * \param head This is a pointer to the list head structure
  499. * \param var This is the name of the variable that will hold a pointer to the
  500. * current list entry on each iteration. It must be declared before calling
  501. * this macro.
  502. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  503. * used to link entries of this list together.
  504. *
  505. * This macro is use to loop over (traverse) the entries in a list. It uses a
  506. * \a for loop, and supplies the enclosed code with a pointer to each list
  507. * entry as it loops. It is typically used as follows:
  508. * \code
  509. * static AST_DLLIST_HEAD(entry_list, list_entry) entries;
  510. * ...
  511. * struct list_entry {
  512. * ...
  513. * AST_DLLIST_ENTRY(list_entry) list;
  514. * }
  515. * ...
  516. * struct list_entry *current;
  517. * ...
  518. * AST_DLLIST_TRAVERSE(&entries, current, list) {
  519. * (do something with current here)
  520. * }
  521. * \endcode
  522. * \warning If you modify the forward-link pointer contained in the \a current entry while
  523. * inside the loop, the behavior will be unpredictable. At a minimum, the following
  524. * macros will modify the forward-link pointer, and should not be used inside
  525. * AST_DLLIST_TRAVERSE() against the entry pointed to by the \a current pointer without
  526. * careful consideration of their consequences:
  527. * \li AST_DLLIST_NEXT() (when used as an lvalue)
  528. * \li AST_DLLIST_INSERT_AFTER()
  529. * \li AST_DLLIST_INSERT_HEAD()
  530. * \li AST_DLLIST_INSERT_TAIL()
  531. * \since 1.6.1
  532. */
  533. #define AST_DLLIST_TRAVERSE(head,var,field) \
  534. AST_DLLIST_TRAVERSE_DIRECTION(head, var, field, first)
  535. #define AST_RWDLLIST_TRAVERSE AST_DLLIST_TRAVERSE
  536. /*!
  537. * \brief Loops over (traverses) the entries in a list in reverse order, starting at the end.
  538. * \param head This is a pointer to the list head structure
  539. * \param var This is the name of the variable that will hold a pointer to the
  540. * current list entry on each iteration. It must be declared before calling
  541. * this macro.
  542. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  543. * used to link entries of this list together.
  544. *
  545. * This macro is use to loop over (traverse) the entries in a list in reverse order. It uses a
  546. * \a for loop, and supplies the enclosed code with a pointer to each list
  547. * entry as it loops. It is typically used as follows:
  548. * \code
  549. * static AST_DLLIST_HEAD(entry_list, list_entry) entries;
  550. * ...
  551. * struct list_entry {
  552. * ...
  553. * AST_DLLIST_ENTRY(list_entry) list;
  554. * }
  555. * ...
  556. * struct list_entry *current;
  557. * ...
  558. * AST_DLLIST_TRAVERSE_BACKWARDS(&entries, current, list) {
  559. * (do something with current here)
  560. * }
  561. * \endcode
  562. * \warning If you modify the forward-link pointer contained in the \a current entry while
  563. * inside the loop, the behavior will be unpredictable. At a minimum, the following
  564. * macros will modify the forward-link pointer, and should not be used inside
  565. * AST_DLLIST_TRAVERSE() against the entry pointed to by the \a current pointer without
  566. * careful consideration of their consequences:
  567. * \li AST_DLLIST_PREV() (when used as an lvalue)
  568. * \li AST_DLLIST_INSERT_BEFORE()
  569. * \li AST_DLLIST_INSERT_HEAD()
  570. * \li AST_DLLIST_INSERT_TAIL()
  571. * \since 1.6.1
  572. */
  573. #define AST_DLLIST_TRAVERSE_BACKWARDS(head,var,field) \
  574. AST_DLLIST_TRAVERSE_DIRECTION(head, var, field, last)
  575. #define AST_RWDLLIST_TRAVERSE_BACKWARDS AST_DLLIST_TRAVERSE_BACKWARDS
  576. /*!
  577. * \brief Safe traversal of a doublly linked list using the specified direction list.
  578. *
  579. * \param head List head structure pointer.
  580. * \param var This is the name of the variable that will hold a pointer to the
  581. * current list node on each iteration. It must be declared before calling
  582. * this macro.
  583. * \param field List node field for the next node information. (declared using AST_DLLIST_ENTRY())
  584. * \param start Specified list node to start traversal: first or last
  585. *
  586. * This macro is used to safely loop over (traverse) the nodes in a list. It
  587. * uses a \a for loop, and supplies the enclosed code with a pointer to each list
  588. * node as it loops. It is typically used as follows:
  589. *
  590. * \code
  591. * static AST_DLLIST_HEAD(entry_list, list_entry) entries;
  592. * ...
  593. * struct list_entry {
  594. * ...
  595. * AST_DLLIST_ENTRY(list_entry) list;
  596. * }
  597. * ...
  598. * struct list_entry *current;
  599. * ...
  600. * AST_DLLIST_TRAVERSE_DIRECTION_SAFE_BEGIN(&entries, current, list, first) {
  601. * (do something with current here (travers list in forward direction))
  602. * }
  603. * ...
  604. * AST_DLLIST_TRAVERSE_DIRECTION_SAFE_BEGIN(&entries, current, list, last) {
  605. * (do something with current here (travers list in reverse direction))
  606. * }
  607. * AST_DLLIST_TRAVERSE_DIRECTION_SAFE_END;
  608. * \endcode
  609. *
  610. * It differs from AST_DLLIST_TRAVERSE() in that the code inside the loop can modify
  611. * (or even free, after calling AST_DLLIST_REMOVE_CURRENT()) the entry pointed to by
  612. * the \a current pointer without affecting the loop traversal.
  613. *
  614. * \since 11
  615. */
  616. #define AST_DLLIST_TRAVERSE_DIRECTION_SAFE_BEGIN(head, var, field, start) \
  617. do { \
  618. typeof((head)) __list_head = (head); \
  619. typeof(__list_head->first) __list_current; \
  620. typeof(__list_head->first) __list_first; \
  621. typeof(__list_head->first) __list_last; \
  622. typeof(__list_head->first) __list_next; \
  623. for ((var) = __list_head->start, \
  624. __list_current = (var), \
  625. __list_first = (var) ? (var)->field.first : NULL, \
  626. __list_last = (var) ? (var)->field.last : NULL, \
  627. __list_next = (var) ? AST_DLLIST_NEXT_DIRECTION(var, field, start) : NULL; \
  628. (var); \
  629. (void) __list_current,/* To quiet compiler? */ \
  630. (void) __list_first,/* To quiet compiler? */ \
  631. (void) __list_last,/* To quiet compiler? */ \
  632. (var) = __list_next, \
  633. __list_current = (var), \
  634. __list_first = (var) ? (var)->field.first : NULL, \
  635. __list_last = (var) ? (var)->field.last : NULL, \
  636. __list_next = (var) ? AST_DLLIST_NEXT_DIRECTION(var, field, start) : NULL \
  637. )
  638. #define AST_RWDLLIST_TRAVERSE_DIRECTION_SAFE_BEGIN AST_DLLIST_TRAVERSE_DIRECTION_SAFE_BEGIN
  639. /*!
  640. * \brief Inserts a list node before the current node during a traversal.
  641. * \param elm This is a pointer to the entry to be inserted.
  642. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  643. * used to link nodes of this list together.
  644. *
  645. * \since 1.6.1
  646. */
  647. #define AST_DLLIST_INSERT_BEFORE_CURRENT(elm, field) \
  648. do { \
  649. typeof((elm)) __elm = (elm); \
  650. __elm->field.last = __list_last; \
  651. __elm->field.first = __list_current; \
  652. if (__list_head->first == __list_current) { \
  653. __list_head->first = __elm; \
  654. } else { \
  655. __list_last->field.first = __elm; \
  656. } \
  657. __list_current->field.last = __elm; \
  658. if (__list_next == __list_last) { \
  659. __list_next = __elm; \
  660. } \
  661. __list_last = __elm; \
  662. } while (0)
  663. #define AST_RWDLLIST_INSERT_BEFORE_CURRENT AST_DLLIST_INSERT_BEFORE_CURRENT
  664. /*!
  665. * \brief Inserts a list node after the current node during a traversal.
  666. * \param elm This is a pointer to the node to be inserted.
  667. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  668. * used to link nodes of this list together.
  669. *
  670. * \since 11
  671. */
  672. #define AST_DLLIST_INSERT_AFTER_CURRENT(elm, field) \
  673. do { \
  674. typeof((elm)) __elm = (elm); \
  675. __elm->field.first = __list_first; \
  676. __elm->field.last = __list_current; \
  677. if (__list_head->last == __list_current) { \
  678. __list_head->last = __elm; \
  679. } else { \
  680. __list_first->field.last = __elm; \
  681. } \
  682. __list_current->field.first = __elm; \
  683. if (__list_next == __list_first) { \
  684. __list_next = __elm; \
  685. } \
  686. __list_first = __elm; \
  687. } while (0)
  688. #define AST_RWDLLIST_INSERT_AFTER_CURRENT AST_DLLIST_INSERT_AFTER_CURRENT
  689. /*!
  690. * \brief Removes the \a current entry from a list during a traversal.
  691. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  692. * used to link entries of this list together.
  693. *
  694. * \note This macro can \b only be used inside an AST_DLLIST_TRAVERSE_SAFE_BEGIN()
  695. * block; it is used to unlink the current entry from the list without affecting
  696. * the list traversal (and without having to re-traverse the list to modify the
  697. * previous entry, if any).
  698. * \since 1.6.1
  699. */
  700. #define AST_DLLIST_REMOVE_CURRENT(field) \
  701. do { \
  702. if (__list_first) { \
  703. __list_first->field.last = __list_last; \
  704. } else { \
  705. __list_head->last = __list_last; \
  706. } \
  707. if (__list_last) { \
  708. __list_last->field.first = __list_first; \
  709. } else { \
  710. __list_head->first = __list_first; \
  711. } \
  712. __list_current->field.first = NULL; \
  713. __list_current->field.last = NULL; \
  714. __list_current = NULL; \
  715. } while (0)
  716. #define AST_RWDLLIST_REMOVE_CURRENT AST_DLLIST_REMOVE_CURRENT
  717. /*!
  718. * \brief Move the current list entry to another list at the tail.
  719. *
  720. * \note This is a silly macro. It should be done explicitly
  721. * otherwise the field parameter must be the same for the two
  722. * lists.
  723. *
  724. * AST_DLLIST_REMOVE_CURRENT(field);
  725. * AST_DLLIST_INSERT_TAIL(newhead, var, other_field);
  726. */
  727. #define AST_DLLIST_MOVE_CURRENT(newhead, field) \
  728. do { \
  729. typeof ((newhead)->first) __list_cur = __list_current; \
  730. AST_DLLIST_REMOVE_CURRENT(field); \
  731. AST_DLLIST_INSERT_TAIL((newhead), __list_cur, field); \
  732. } while (0)
  733. #define AST_RWDLLIST_MOVE_CURRENT AST_DLLIST_MOVE_CURRENT
  734. /*!
  735. * \brief Move the current list entry to another list at the head.
  736. *
  737. * \note This is a silly macro. It should be done explicitly
  738. * otherwise the field parameter must be the same for the two
  739. * lists.
  740. *
  741. * AST_DLLIST_REMOVE_CURRENT(field);
  742. * AST_DLLIST_INSERT_HEAD(newhead, var, other_field);
  743. */
  744. #define AST_DLLIST_MOVE_CURRENT_BACKWARDS(newhead, field) \
  745. do { \
  746. typeof ((newhead)->first) __list_cur = __list_current; \
  747. AST_DLLIST_REMOVE_CURRENT(field); \
  748. AST_DLLIST_INSERT_HEAD((newhead), __list_cur, field); \
  749. } while (0)
  750. #define AST_RWDLLIST_MOVE_CURRENT_BACKWARDS AST_DLLIST_MOVE_CURRENT_BACKWARDS
  751. #define AST_DLLIST_TRAVERSE_DIRECTION_SAFE_END \
  752. } while (0)
  753. #define AST_RWDLLIST_TRAVERSE_DIRECTION_SAFE_END AST_DLLIST_TRAVERSE_DIRECTION_SAFE_END
  754. /*!
  755. * \brief Loops safely over (traverses) the entries in a list.
  756. * \param head This is a pointer to the list head structure
  757. * \param var This is the name of the variable that will hold a pointer to the
  758. * current list entry on each iteration. It must be declared before calling
  759. * this macro.
  760. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  761. * used to link entries of this list together.
  762. *
  763. * This macro is used to safely loop over (traverse) the entries in a list. It
  764. * uses a \a for loop, and supplies the enclosed code with a pointer to each list
  765. * entry as it loops. It is typically used as follows:
  766. *
  767. * \code
  768. * static AST_DLLIST_HEAD(entry_list, list_entry) entries;
  769. * ...
  770. * struct list_entry {
  771. * ...
  772. * AST_DLLIST_ENTRY(list_entry) list;
  773. * }
  774. * ...
  775. * struct list_entry *current;
  776. * ...
  777. * AST_DLLIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
  778. * (do something with current here)
  779. * }
  780. * AST_DLLIST_TRAVERSE_SAFE_END;
  781. * \endcode
  782. *
  783. * It differs from AST_DLLIST_TRAVERSE() in that the code inside the loop can modify
  784. * (or even free, after calling AST_DLLIST_REMOVE_CURRENT()) the entry pointed to by
  785. * the \a current pointer without affecting the loop traversal.
  786. * \since 1.6.1
  787. */
  788. #define AST_DLLIST_TRAVERSE_SAFE_BEGIN(head, var, field) \
  789. AST_DLLIST_TRAVERSE_DIRECTION_SAFE_BEGIN(head, var, field, first)
  790. #define AST_RWDLLIST_TRAVERSE_SAFE_BEGIN AST_DLLIST_TRAVERSE_SAFE_BEGIN
  791. /*!
  792. * \brief Loops safely over (traverses) the entries in a list.
  793. * \param head This is a pointer to the list head structure
  794. * \param var This is the name of the variable that will hold a pointer to the
  795. * current list entry on each iteration. It must be declared before calling
  796. * this macro.
  797. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  798. * used to link entries of this list together.
  799. *
  800. * This macro is used to safely loop over (traverse) the entries in a list. It
  801. * uses a \a for loop, and supplies the enclosed code with a pointer to each list
  802. * entry as it loops. It is typically used as follows:
  803. *
  804. * \code
  805. * static AST_DLLIST_HEAD(entry_list, list_entry) entries;
  806. * ...
  807. * struct list_entry {
  808. * ...
  809. * AST_DLLIST_ENTRY(list_entry) list;
  810. * }
  811. * ...
  812. * struct list_entry *current;
  813. * ...
  814. * AST_DLLIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
  815. * (do something with current here)
  816. * }
  817. * AST_DLLIST_TRAVERSE_SAFE_END;
  818. * \endcode
  819. *
  820. * It differs from AST_DLLIST_TRAVERSE() in that the code inside the loop can modify
  821. * (or even free, after calling AST_DLLIST_REMOVE_CURRENT()) the entry pointed to by
  822. * the \a current pointer without affecting the loop traversal.
  823. * \since 1.6.1
  824. */
  825. #define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(head, var, field) \
  826. AST_DLLIST_TRAVERSE_DIRECTION_SAFE_BEGIN(head, var, field, last)
  827. #define AST_RWDLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN
  828. /*!
  829. * \brief Inserts a list entry after the current entry during a backwards traversal. Since
  830. * this is a backwards traversal, this will insert the entry AFTER the current
  831. * element. Since this is a backwards traveral, though, this would be BEFORE
  832. * the current entry in traversal order. Confusing?
  833. * \param elm This is a pointer to the entry to be inserted.
  834. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  835. * used to link entries of this list together.
  836. *
  837. * \since 1.6.1
  838. */
  839. #define AST_DLLIST_INSERT_BEFORE_CURRENT_BACKWARDS(elm, field) \
  840. AST_DLLIST_INSERT_AFTER_CURRENT(elm, field)
  841. #define AST_RWDLLIST_INSERT_BEFORE_CURRENT_BACKWARDS AST_DLLIST_INSERT_BEFORE_CURRENT_BACKWARDS
  842. /*!
  843. * \brief Closes a safe loop traversal block.
  844. * \since 1.6.1
  845. */
  846. #define AST_DLLIST_TRAVERSE_SAFE_END AST_DLLIST_TRAVERSE_DIRECTION_SAFE_END
  847. #define AST_RWDLLIST_TRAVERSE_SAFE_END AST_DLLIST_TRAVERSE_SAFE_END
  848. /*!
  849. * \brief Closes a safe loop traversal block.
  850. * \since 1.6.1
  851. */
  852. #define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END AST_DLLIST_TRAVERSE_DIRECTION_SAFE_END
  853. #define AST_RWDLLIST_TRAVERSE_BACKWARDS_SAFE_END AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END
  854. /*!
  855. * \brief Initializes a list head structure.
  856. * \param head This is a pointer to the list head structure
  857. *
  858. * This macro initializes a list head structure by setting the head
  859. * entry to \a NULL (empty list) and recreating the embedded lock.
  860. * \since 1.6.1
  861. */
  862. #define AST_DLLIST_HEAD_INIT(head) \
  863. { \
  864. (head)->first = NULL; \
  865. (head)->last = NULL; \
  866. ast_mutex_init(&(head)->lock); \
  867. }
  868. /*!
  869. * \brief Initializes an rwlist head structure.
  870. * \param head This is a pointer to the list head structure
  871. *
  872. * This macro initializes a list head structure by setting the head
  873. * entry to \a NULL (empty list) and recreating the embedded lock.
  874. * \since 1.6.1
  875. */
  876. #define AST_RWDLLIST_HEAD_INIT(head) \
  877. { \
  878. (head)->first = NULL; \
  879. (head)->last = NULL; \
  880. ast_rwlock_init(&(head)->lock); \
  881. }
  882. /*!
  883. * \brief Destroys a list head structure.
  884. * \param head This is a pointer to the list head structure
  885. *
  886. * This macro destroys a list head structure by setting the head
  887. * entry to \a NULL (empty list) and destroying the embedded lock.
  888. * It does not free the structure from memory.
  889. * \since 1.6.1
  890. */
  891. #define AST_DLLIST_HEAD_DESTROY(head) \
  892. { \
  893. (head)->first = NULL; \
  894. (head)->last = NULL; \
  895. ast_mutex_destroy(&(head)->lock); \
  896. }
  897. /*!
  898. * \brief Destroys an rwlist head structure.
  899. * \param head This is a pointer to the list head structure
  900. *
  901. * This macro destroys a list head structure by setting the head
  902. * entry to \a NULL (empty list) and destroying the embedded lock.
  903. * It does not free the structure from memory.
  904. * \since 1.6.1
  905. */
  906. #define AST_RWDLLIST_HEAD_DESTROY(head) \
  907. { \
  908. (head)->first = NULL; \
  909. (head)->last = NULL; \
  910. ast_rwlock_destroy(&(head)->lock); \
  911. }
  912. /*!
  913. * \brief Initializes a list head structure.
  914. * \param head This is a pointer to the list head structure
  915. *
  916. * This macro initializes a list head structure by setting the head
  917. * entry to \a NULL (empty list). There is no embedded lock handling
  918. * with this macro.
  919. * \since 1.6.1
  920. */
  921. #define AST_DLLIST_HEAD_INIT_NOLOCK(head) \
  922. { \
  923. (head)->first = NULL; \
  924. (head)->last = NULL; \
  925. }
  926. /*!
  927. * \brief Inserts a list entry after a given entry.
  928. * \param head This is a pointer to the list head structure
  929. * \param listelm This is a pointer to the entry after which the new entry should
  930. * be inserted.
  931. * \param elm This is a pointer to the entry to be inserted.
  932. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  933. * used to link entries of this list together.
  934. * \since 1.6.1
  935. */
  936. #define AST_DLLIST_INSERT_AFTER(head, listelm, elm, field) \
  937. do { \
  938. typeof((listelm)) __listelm = (listelm); \
  939. typeof((elm)) __elm = (elm); \
  940. __elm->field.first = __listelm->field.first; \
  941. __elm->field.last = __listelm; \
  942. if ((head)->last == __listelm) { \
  943. (head)->last = __elm; \
  944. } else { \
  945. __listelm->field.first->field.last = __elm; \
  946. } \
  947. __listelm->field.first = __elm; \
  948. } while (0)
  949. #define AST_RWDLLIST_INSERT_AFTER AST_DLLIST_INSERT_AFTER
  950. /*!
  951. * \brief Inserts a list entry before a given entry.
  952. * \param head This is a pointer to the list head structure
  953. * \param listelm This is a pointer to the entry before which the new entry should
  954. * be inserted.
  955. * \param elm This is a pointer to the entry to be inserted.
  956. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  957. * used to link entries of this list together.
  958. * \since 1.6.1
  959. */
  960. #define AST_DLLIST_INSERT_BEFORE(head, listelm, elm, field) \
  961. do { \
  962. typeof((listelm)) __listelm = (listelm); \
  963. typeof((elm)) __elm = (elm); \
  964. __elm->field.last = __listelm->field.last; \
  965. __elm->field.first = __listelm; \
  966. if ((head)->first == __listelm) { \
  967. (head)->first = __elm; \
  968. } else { \
  969. __listelm->field.last->field.first = __elm; \
  970. } \
  971. __listelm->field.last = __elm; \
  972. } while (0)
  973. #define AST_RWDLLIST_INSERT_BEFORE AST_DLLIST_INSERT_BEFORE
  974. /*!
  975. * \brief Inserts a list entry at the head of a list.
  976. * \param head This is a pointer to the list head structure
  977. * \param elm This is a pointer to the entry to be inserted.
  978. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  979. * used to link entries of this list together.
  980. * \since 1.6.1
  981. */
  982. #define AST_DLLIST_INSERT_HEAD(head, elm, field) \
  983. do { \
  984. typeof((elm)) __elm = (elm); \
  985. __elm->field.last = NULL; \
  986. __elm->field.first = (head)->first; \
  987. if (!(head)->first) { \
  988. (head)->last = __elm; \
  989. } else { \
  990. (head)->first->field.last = __elm; \
  991. } \
  992. (head)->first = __elm; \
  993. } while (0)
  994. #define AST_RWDLLIST_INSERT_HEAD AST_DLLIST_INSERT_HEAD
  995. /*!
  996. * \brief Appends a list entry to the tail of a list.
  997. * \param head This is a pointer to the list head structure
  998. * \param elm This is a pointer to the entry to be appended.
  999. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  1000. * used to link entries of this list together.
  1001. *
  1002. * Note: The link field in the appended entry is \b not modified, so if it is
  1003. * actually the head of a list itself, the entire list will be appended
  1004. * temporarily (until the next AST_DLLIST_INSERT_TAIL is performed).
  1005. * \since 1.6.1
  1006. */
  1007. #define AST_DLLIST_INSERT_TAIL(head, elm, field) \
  1008. do { \
  1009. typeof((elm)) __elm = (elm); \
  1010. __elm->field.first = NULL; \
  1011. if (!(head)->first) { \
  1012. __elm->field.last = NULL; \
  1013. (head)->first = __elm; \
  1014. } else { \
  1015. __elm->field.last = (head)->last; \
  1016. (head)->last->field.first = __elm; \
  1017. } \
  1018. (head)->last = __elm; \
  1019. } while (0)
  1020. #define AST_RWDLLIST_INSERT_TAIL AST_DLLIST_INSERT_TAIL
  1021. /*!
  1022. * \brief Appends a whole list to the tail of a list.
  1023. * \param head This is a pointer to the list head structure
  1024. * \param list This is a pointer to the list to be appended.
  1025. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  1026. * used to link entries of this list together.
  1027. *
  1028. * Note: The source list (the \a list parameter) will be empty after
  1029. * calling this macro (the list entries are \b moved to the target list).
  1030. * \since 1.6.1
  1031. */
  1032. #define AST_DLLIST_APPEND_DLLIST(head, list, field) \
  1033. do { \
  1034. if (!(head)->first) { \
  1035. (head)->first = (list)->first; \
  1036. (head)->last = (list)->last; \
  1037. } else { \
  1038. (head)->last->field.first = (list)->first; \
  1039. (list)->first->field.last = (head)->last; \
  1040. (head)->last = (list)->last; \
  1041. } \
  1042. (list)->first = NULL; \
  1043. (list)->last = NULL; \
  1044. } while (0)
  1045. #define AST_RWDLLIST_APPEND_DLLIST AST_DLLIST_APPEND_DLLIST
  1046. /*!
  1047. * \brief Removes and returns the head entry from a list.
  1048. * \param head This is a pointer to the list head structure
  1049. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  1050. * used to link entries of this list together.
  1051. *
  1052. * Removes the head entry from the list, and returns a pointer to it.
  1053. * This macro is safe to call on an empty list.
  1054. * \since 1.6.1
  1055. */
  1056. #define AST_DLLIST_REMOVE_HEAD(head, field) \
  1057. ({ \
  1058. typeof((head)->first) cur = (head)->first; \
  1059. if (cur) { \
  1060. (head)->first = cur->field.first; \
  1061. if ((head)->first) { \
  1062. (head)->first->field.last = NULL; \
  1063. } \
  1064. cur->field.first = NULL; \
  1065. cur->field.last = NULL; \
  1066. if ((head)->last == cur) { \
  1067. (head)->last = NULL; \
  1068. } \
  1069. } \
  1070. cur; \
  1071. })
  1072. #define AST_RWDLLIST_REMOVE_HEAD AST_DLLIST_REMOVE_HEAD
  1073. /*!
  1074. * \brief Removes and returns the tail node from a list.
  1075. * \param head This is a pointer to the list head structure
  1076. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  1077. * used to link nodes of this list together.
  1078. *
  1079. * Removes the tail entry from the list, and returns a pointer to it.
  1080. * This macro is safe to call on an empty list.
  1081. * \since 11
  1082. */
  1083. #define AST_DLLIST_REMOVE_TAIL(head, field) \
  1084. ({ \
  1085. typeof((head)->last) cur = (head)->last; \
  1086. if (cur) { \
  1087. (head)->last = cur->field.last; \
  1088. if ((head)->last) { \
  1089. (head)->last->field.first = NULL; \
  1090. } \
  1091. cur->field.first = NULL; \
  1092. cur->field.last = NULL; \
  1093. if ((head)->first == cur) { \
  1094. (head)->first = NULL; \
  1095. } \
  1096. } \
  1097. cur; \
  1098. })
  1099. #define AST_RWDLLIST_REMOVE_TAIL AST_DLLIST_REMOVE_TAIL
  1100. /*!
  1101. * \brief Removes a specific entry from a list.
  1102. * \param head This is a pointer to the list head structure
  1103. * \param elm This is a pointer to the entry to be removed.
  1104. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  1105. * used to link entries of this list together.
  1106. * \warning The removed entry is \b not freed.
  1107. * \since 1.6.1
  1108. */
  1109. #define AST_DLLIST_REMOVE(head, elm, field) \
  1110. do { \
  1111. typeof((elm)) __elm = (elm); \
  1112. if (__elm) { \
  1113. if (__elm->field.first) { \
  1114. __elm->field.first->field.last = __elm->field.last; \
  1115. } else { \
  1116. (head)->last = __elm->field.last; \
  1117. } \
  1118. if (__elm->field.last) { \
  1119. __elm->field.last->field.first = __elm->field.first; \
  1120. } else { \
  1121. (head)->first = __elm->field.first; \
  1122. } \
  1123. __elm->field.first = NULL; \
  1124. __elm->field.last = NULL; \
  1125. } \
  1126. } while (0)
  1127. #define AST_RWDLLIST_REMOVE AST_DLLIST_REMOVE
  1128. /*!
  1129. * \brief Removes a specific node from a list if it is in the list.
  1130. * \param head This is a pointer to the list head structure
  1131. * \param elm This is a pointer to the node to be removed.
  1132. * \param field This is the name of the field (declared using AST_DLLIST_ENTRY())
  1133. * used to link nodes of this list together.
  1134. * \warning The removed node is \b not freed.
  1135. * \return elm if the list had elm in it.
  1136. * \return NULL if not.
  1137. * \since 11
  1138. */
  1139. #define AST_DLLIST_REMOVE_VERIFY(head, elm, field) \
  1140. ({ \
  1141. typeof((elm)) __res = AST_DLLIST_IS_MEMBER(head, elm, field); \
  1142. AST_DLLIST_REMOVE(head, __res, field); \
  1143. __res; \
  1144. })
  1145. #define AST_RWDLLIST_REMOVE_VERIFY AST_DLLIST_REMOVE_VERIFY
  1146. #endif /* _ASTERISK_DLINKEDLISTS_H */