pollfd.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /** @file pollfd.c
  2. */
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. #include <unistd.h>
  9. #include <errno.h>
  10. #include <sys/types.h>
  11. #include <poll.h>
  12. #include "faux/faux.h"
  13. #include "faux/net.h"
  14. #include "faux/vec.h"
  15. #include "private.h"
  16. /** @brief Callback function to search specified fd within pollfd structures.
  17. */
  18. static int cmp_by_fd(const void *key, const void *item)
  19. {
  20. int k = *(int *)key;
  21. struct pollfd *i = (struct pollfd *)item;
  22. if (k == i->fd)
  23. return 0;
  24. return -1;
  25. }
  26. /** @brief Allocates memory for faux_pollfd_t object.
  27. *
  28. * @return Allocated faux_pollfd_t object or NULL on error.
  29. */
  30. faux_pollfd_t *faux_pollfd_new(void)
  31. {
  32. faux_pollfd_t *faux_pollfd = NULL;
  33. faux_pollfd = faux_zmalloc(sizeof(*faux_pollfd));
  34. assert(faux_pollfd);
  35. if (!faux_pollfd)
  36. return NULL;
  37. faux_pollfd->vec = faux_vec_new(sizeof(struct pollfd), cmp_by_fd);
  38. return faux_pollfd;
  39. }
  40. /** @brief Frees previously allocated faux_pollfd_t object.
  41. *
  42. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  43. */
  44. void faux_pollfd_free(faux_pollfd_t *faux_pollfd)
  45. {
  46. if (!faux_pollfd)
  47. return;
  48. faux_vec_free(faux_pollfd->vec);
  49. faux_free(faux_pollfd);
  50. }
  51. /** @brief Returns whole "struct pollfd" vector.
  52. *
  53. * It can be used while poll() call.
  54. *
  55. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  56. * @return Pointer to "struct pollfd" vector or NULL on error.
  57. */
  58. struct pollfd *faux_pollfd_vector(faux_pollfd_t *faux_pollfd)
  59. {
  60. assert(faux_pollfd);
  61. if (!faux_pollfd)
  62. return NULL;
  63. return faux_vec_data(faux_pollfd->vec);
  64. }
  65. /** @brief Returns number of "struct pollfd" items within object.
  66. *
  67. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  68. * @return Number of items.
  69. */
  70. size_t faux_pollfd_len(faux_pollfd_t *faux_pollfd)
  71. {
  72. assert(faux_pollfd);
  73. if (!faux_pollfd)
  74. return 0;
  75. return faux_vec_len(faux_pollfd->vec);
  76. }
  77. /** @brief Returns "struct pollfd" item by specified index.
  78. *
  79. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  80. * @param [in] index Index of item to get.
  81. * @return Pointer to item or NULL on error.
  82. */
  83. struct pollfd *faux_pollfd_item(faux_pollfd_t *faux_pollfd, unsigned int index)
  84. {
  85. assert(faux_pollfd);
  86. if (!faux_pollfd)
  87. return NULL;
  88. return (struct pollfd *)faux_vec_item(faux_pollfd->vec, index);
  89. }
  90. /** @brief Finds item with specified fd value.
  91. *
  92. * File descriptor is a key for array. Object can contain the only one item
  93. * with the same fd value.
  94. *
  95. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  96. * @param [in] fd File descriptor to search for.
  97. * @return Pointer to found item or NULL on error or in "not found" case.
  98. */
  99. struct pollfd *faux_pollfd_find(faux_pollfd_t *faux_pollfd, int fd)
  100. {
  101. int index = 0;
  102. assert(faux_pollfd);
  103. if (!faux_pollfd)
  104. return NULL;
  105. assert(fd >= 0);
  106. if (fd < 0)
  107. return NULL;
  108. index = faux_vec_find(faux_pollfd->vec, &fd, 0);
  109. if (index < 0)
  110. return NULL;
  111. return (struct pollfd *)faux_vec_item(faux_pollfd->vec, index);
  112. }
  113. /** @brief Adds new item to object.
  114. *
  115. * The file descriptors are unique within array. So function try to find item
  116. * with the specified fd. If it's found the correspondent item will be returned
  117. * but new item will not be created.
  118. *
  119. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  120. * @param [in] fd File descriptor to set to newly created item.
  121. * @param [in] events The events interested in.
  122. * @return Pointer to new item or NULL on error.
  123. */
  124. struct pollfd *faux_pollfd_add(faux_pollfd_t *faux_pollfd, int fd, short events)
  125. {
  126. struct pollfd *pollfd = NULL;
  127. assert(faux_pollfd);
  128. if (!faux_pollfd)
  129. return NULL;
  130. assert(fd >= 0);
  131. if (fd < 0)
  132. return NULL;
  133. // Don't add duplicated fd
  134. pollfd = faux_pollfd_find(faux_pollfd, fd);
  135. if (!pollfd) {
  136. // Create new item
  137. pollfd = faux_vec_add(faux_pollfd->vec);
  138. assert(pollfd);
  139. if (!pollfd)
  140. return NULL;
  141. pollfd->fd = fd;
  142. }
  143. pollfd->events = events;
  144. return pollfd;
  145. }
  146. /** @brief Removes item specified by fd.
  147. *
  148. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  149. * @param [in] fd File descriptor to remove.
  150. * @return 0 - success, < 0 on error.
  151. */
  152. int faux_pollfd_del_by_fd(faux_pollfd_t *faux_pollfd, int fd)
  153. {
  154. int index = 0;
  155. assert(faux_pollfd);
  156. if (!faux_pollfd)
  157. return -1;
  158. assert(fd >= 0);
  159. if (fd < 0)
  160. return -1;
  161. index = faux_vec_find(faux_pollfd->vec, &fd, 0);
  162. if (index < 0) // Not found
  163. return -1;
  164. return faux_vec_del(faux_pollfd->vec, index);
  165. }
  166. /** @brief Removes item specified by index.
  167. *
  168. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  169. * @param [in] index Index of item to remove.
  170. * @return 0 - success, < 0 on error.
  171. */
  172. int faux_pollfd_del_by_index(faux_pollfd_t *faux_pollfd, unsigned int index)
  173. {
  174. assert(faux_pollfd);
  175. if (!faux_pollfd)
  176. return -1;
  177. return faux_vec_del(faux_pollfd->vec, index);
  178. }
  179. /** @brief Initilizes iterator to iterate through all the vector.
  180. *
  181. * @sa faux_pollfd_each()
  182. * @sa faux_pollfd_each_active()
  183. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  184. * @param [out] iterator Iterator to initialize.
  185. */
  186. void faux_pollfd_init_iterator(faux_pollfd_t *faux_pollfd, faux_pollfd_iterator_t *iterator)
  187. {
  188. assert(faux_pollfd);
  189. if (!faux_pollfd)
  190. return;
  191. if (!iterator)
  192. return;
  193. *iterator = 0;
  194. }
  195. /** @brief Iterate through all the vector.
  196. *
  197. * The iterator must be initialized first by faux_pollfd_init_iterator().
  198. *
  199. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  200. * @param [out] iterator Initialized iterator.
  201. * @return Pointer to item or NULL on error or on end of vector.
  202. */
  203. struct pollfd *faux_pollfd_each(faux_pollfd_t *faux_pollfd, faux_pollfd_iterator_t *iterator)
  204. {
  205. unsigned int old_iterator = 0;
  206. assert(faux_pollfd);
  207. if (!faux_pollfd)
  208. return NULL;
  209. if (!iterator)
  210. return NULL;
  211. old_iterator = *iterator;
  212. (*iterator)++;
  213. return faux_pollfd_item(faux_pollfd, old_iterator);
  214. }
  215. /** @brief Iterate through all active items of vector.
  216. *
  217. * The iterator must be initialized first by faux_pollfd_init_iterator().
  218. * Function returns items that has non-null value in "revent" field i.e.
  219. * active items.
  220. *
  221. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  222. * @param [out] iterator Initialized iterator.
  223. * @return Pointer to active item or NULL on error or on end of vector.
  224. */
  225. struct pollfd *faux_pollfd_each_active(faux_pollfd_t *faux_pollfd, faux_pollfd_iterator_t *iterator)
  226. {
  227. struct pollfd *pollfd = NULL;
  228. assert(faux_pollfd);
  229. if (!faux_pollfd)
  230. return NULL;
  231. if (!iterator)
  232. return NULL;
  233. while ((pollfd = faux_pollfd_each(faux_pollfd, iterator))) {
  234. if (pollfd->revents != 0)
  235. return pollfd;
  236. }
  237. return NULL;
  238. }