aos_list.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #ifndef LIBAOS_LIST_H
  2. #define LIBAOS_LIST_H
  3. #include <apr_general.h>
  4. // from kernel list
  5. typedef struct aos_list_s aos_list_t;
  6. struct aos_list_s {
  7. aos_list_t *next, *prev;
  8. };
  9. #define aos_list_head_init(name) {&(name), &(name)}
  10. #define aos_list_init(ptr) do { \
  11. (ptr)->next = (ptr); \
  12. (ptr)->prev = (ptr); \
  13. } while (0)
  14. static APR_INLINE void __aos_list_add(aos_list_t *list, aos_list_t *prev, aos_list_t *next)
  15. {
  16. next->prev = list;
  17. list->next = next;
  18. list->prev = prev;
  19. prev->next = list;
  20. }
  21. // list head to add it before
  22. static APR_INLINE void aos_list_add_tail(aos_list_t *list, aos_list_t *head)
  23. {
  24. __aos_list_add(list, head->prev, head);
  25. }
  26. static APR_INLINE void __aos_list_del(aos_list_t *prev, aos_list_t *next)
  27. {
  28. next->prev = prev;
  29. prev->next = next;
  30. }
  31. // deletes entry from list
  32. static APR_INLINE void aos_list_del(aos_list_t *entry)
  33. {
  34. __aos_list_del(entry->prev, entry->next);
  35. aos_list_init(entry);
  36. }
  37. // tests whether a list is empty
  38. static APR_INLINE int aos_list_empty(const aos_list_t *head)
  39. {
  40. return (head->next == head);
  41. }
  42. // move list to new_list
  43. static APR_INLINE void aos_list_movelist(aos_list_t *list, aos_list_t *new_list)
  44. {
  45. if (!aos_list_empty(list)) {
  46. new_list->prev = list->prev;
  47. new_list->next = list->next;
  48. new_list->prev->next = new_list;
  49. new_list->next->prev = new_list;
  50. aos_list_init(list);
  51. } else {
  52. aos_list_init(new_list);
  53. }
  54. }
  55. // get last
  56. #define aos_list_get_last(list, type, member) \
  57. aos_list_empty(list) ? NULL : aos_list_entry((list)->prev, type, member)
  58. // get first
  59. #define aos_list_get_first(list, type, member) \
  60. aos_list_empty(list) ? NULL : aos_list_entry((list)->next, type, member)
  61. #define aos_list_entry(ptr, type, member) \
  62. (type *)( (char *)ptr - APR_OFFSETOF(type, member) )
  63. // traversing
  64. #define aos_list_for_each_entry(postp, pos, head, member) \
  65. for (pos = aos_list_entry((head)->next, postp, member); \
  66. &pos->member != (head); \
  67. pos = aos_list_entry(pos->member.next, postp, member))
  68. #define aos_list_for_each_entry_reverse(postp, pos, head, member) \
  69. for (pos = aos_list_entry((head)->prev, postp, member); \
  70. &pos->member != (head); \
  71. pos = aos_list_entry(pos->member.prev, postp, member))
  72. #define aos_list_for_each_entry_safe(postp, pos, n, head, member) \
  73. for (pos = aos_list_entry((head)->next, postp, member), \
  74. n = aos_list_entry(pos->member.next, postp, member); \
  75. &pos->member != (head); \
  76. pos = n, n = aos_list_entry(n->member.next, postp, member))
  77. #define aos_list_for_each_entry_safe_reverse(postp, pos, n, head, member) \
  78. for (pos = aos_list_entry((head)->prev, postp, member), \
  79. n = aos_list_entry(pos->member.prev, postp, member); \
  80. &pos->member != (head); \
  81. pos = n, n = aos_list_entry(n->member.prev, postp, member))
  82. #endif