io.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. *
  3. * Embedded Linux library
  4. *
  5. * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #include <errno.h>
  26. #include <unistd.h>
  27. #include <stdbool.h>
  28. #include <sys/epoll.h>
  29. #include "useful.h"
  30. #include "main-private.h"
  31. #include "io.h"
  32. #include "private.h"
  33. /**
  34. * SECTION:io
  35. * @short_description: IO support
  36. *
  37. * IO support
  38. */
  39. /**
  40. * l_io:
  41. *
  42. * Opague object representing the IO.
  43. */
  44. struct l_io {
  45. int fd;
  46. uint32_t events;
  47. bool close_on_destroy;
  48. l_io_read_cb_t read_handler;
  49. l_io_destroy_cb_t read_destroy;
  50. void *read_data;
  51. l_io_write_cb_t write_handler;
  52. l_io_destroy_cb_t write_destroy;
  53. void *write_data;
  54. l_io_disconnect_cb_t disconnect_handler;
  55. l_io_destroy_cb_t disconnect_destroy;
  56. void *disconnect_data;
  57. l_io_debug_cb_t debug_handler;
  58. l_io_destroy_cb_t debug_destroy;
  59. void *debug_data;
  60. };
  61. static void io_cleanup(void *user_data)
  62. {
  63. struct l_io *io = user_data;
  64. l_util_debug(io->debug_handler, io->debug_data, "cleanup <%p>", io);
  65. if (io->write_destroy)
  66. io->write_destroy(io->write_data);
  67. io->write_handler = NULL;
  68. io->write_data = NULL;
  69. if (io->read_destroy)
  70. io->read_destroy(io->read_data);
  71. io->read_handler = NULL;
  72. io->read_data = NULL;
  73. if (io->close_on_destroy)
  74. close(io->fd);
  75. io->fd = -1;
  76. }
  77. static void io_closed(struct l_io *io)
  78. {
  79. /*
  80. * Save off copies of disconnect_handler, disconnect_destroy
  81. * and disconnect_data in case the handler calls io_destroy
  82. */
  83. l_io_disconnect_cb_t handler = io->disconnect_handler;
  84. l_io_destroy_cb_t destroy = io->disconnect_destroy;
  85. void *disconnect_data = io->disconnect_data;
  86. io->disconnect_handler = NULL;
  87. io->disconnect_destroy = NULL;
  88. io->disconnect_data = NULL;
  89. if (handler)
  90. handler(io, disconnect_data);
  91. if (destroy)
  92. destroy(disconnect_data);
  93. }
  94. static void io_callback(int fd, uint32_t events, void *user_data)
  95. {
  96. struct l_io *io = user_data;
  97. if ((events & EPOLLIN) && io->read_handler) {
  98. l_util_debug(io->debug_handler, io->debug_data,
  99. "read event <%p>", io);
  100. if (!io->read_handler(io, io->read_data)) {
  101. if (io->read_destroy)
  102. io->read_destroy(io->read_data);
  103. io->read_handler = NULL;
  104. io->read_destroy = NULL;
  105. io->read_data = NULL;
  106. io->events &= ~EPOLLIN;
  107. if (watch_modify(io->fd, io->events, false) == -EBADF) {
  108. io->close_on_destroy = false;
  109. watch_clear(io->fd);
  110. io_closed(io);
  111. return;
  112. }
  113. }
  114. }
  115. if (unlikely(events & (EPOLLERR | EPOLLHUP))) {
  116. bool close_on_destroy = io->close_on_destroy;
  117. int fd = io->fd;
  118. l_util_debug(io->debug_handler, io->debug_data,
  119. "disconnect event <%p>", io);
  120. io_closed(io);
  121. watch_remove(fd, !close_on_destroy);
  122. return;
  123. }
  124. if ((events & EPOLLOUT) && io->write_handler) {
  125. l_util_debug(io->debug_handler, io->debug_data,
  126. "write event <%p>", io);
  127. if (!io->write_handler(io, io->write_data)) {
  128. if (io->write_destroy)
  129. io->write_destroy(io->write_data);
  130. io->write_handler = NULL;
  131. io->write_destroy = NULL;
  132. io->write_data = NULL;
  133. io->events &= ~EPOLLOUT;
  134. if (watch_modify(io->fd, io->events, false) == -EBADF) {
  135. io->close_on_destroy = false;
  136. watch_clear(io->fd);
  137. io_closed(io);
  138. return;
  139. }
  140. }
  141. }
  142. }
  143. /**
  144. * l_io_new:
  145. * @fd: file descriptor
  146. *
  147. * Create new IO handling for a given file descriptor.
  148. *
  149. * Returns: a newly allocated #l_io object
  150. **/
  151. LIB_EXPORT struct l_io *l_io_new(int fd)
  152. {
  153. struct l_io *io;
  154. int err;
  155. if (unlikely(fd < 0))
  156. return NULL;
  157. io = l_new(struct l_io, 1);
  158. io->fd = fd;
  159. io->events = EPOLLHUP | EPOLLERR;
  160. io->close_on_destroy = false;
  161. err = watch_add(io->fd, io->events, io_callback, io, io_cleanup);
  162. if (err) {
  163. l_free(io);
  164. return NULL;
  165. }
  166. return io;
  167. }
  168. /**
  169. * l_io_destroy:
  170. * @io: IO object
  171. *
  172. * Free IO object and close file descriptor (if enabled).
  173. **/
  174. LIB_EXPORT void l_io_destroy(struct l_io *io)
  175. {
  176. if (unlikely(!io))
  177. return;
  178. if (io->fd != -1)
  179. watch_remove(io->fd, !io->close_on_destroy);
  180. io_closed(io);
  181. if (io->debug_destroy)
  182. io->debug_destroy(io->debug_data);
  183. l_free(io);
  184. }
  185. /**
  186. * l_io_get_fd:
  187. * @io: IO object
  188. *
  189. * Returns: file descriptor associated with @io
  190. **/
  191. LIB_EXPORT int l_io_get_fd(struct l_io *io)
  192. {
  193. if (unlikely(!io))
  194. return -1;
  195. return io->fd;
  196. }
  197. /**
  198. * l_io_set_close_on_destroy:
  199. * @io: IO object
  200. * @do_close: setting for destroy handling
  201. *
  202. * Set the automatic closing of the file descriptor when destroying @io.
  203. *
  204. * Returns: #true on success and #false on failure
  205. **/
  206. LIB_EXPORT bool l_io_set_close_on_destroy(struct l_io *io, bool do_close)
  207. {
  208. if (unlikely(!io))
  209. return false;
  210. io->close_on_destroy = do_close;
  211. return true;
  212. }
  213. /**
  214. * l_io_set_read_handler:
  215. * @io: IO object
  216. * @callback: read handler callback function
  217. * @user_data: user data provided to read handler callback function
  218. * @destroy: destroy function for user data
  219. *
  220. * Set read function.
  221. *
  222. * Returns: #true on success and #false on failure
  223. **/
  224. LIB_EXPORT bool l_io_set_read_handler(struct l_io *io, l_io_read_cb_t callback,
  225. void *user_data, l_io_destroy_cb_t destroy)
  226. {
  227. uint32_t events;
  228. int err;
  229. if (unlikely(!io || io->fd < 0))
  230. return false;
  231. l_util_debug(io->debug_handler, io->debug_data,
  232. "set read handler <%p>", io);
  233. if (io->read_destroy)
  234. io->read_destroy(io->read_data);
  235. if (callback)
  236. events = io->events | EPOLLIN;
  237. else
  238. events = io->events & ~EPOLLIN;
  239. io->read_handler = callback;
  240. io->read_destroy = destroy;
  241. io->read_data = user_data;
  242. if (events == io->events)
  243. return true;
  244. err = watch_modify(io->fd, events, false);
  245. if (err)
  246. return false;
  247. io->events = events;
  248. return true;
  249. }
  250. /**
  251. * l_io_set_write_handler:
  252. * @io: IO object
  253. * @callback: write handler callback function
  254. * @user_data: user data provided to write handler callback function
  255. * @destroy: destroy function for user data
  256. *
  257. * Set write function.
  258. *
  259. * Returns: #true on success and #false on failure
  260. **/
  261. LIB_EXPORT bool l_io_set_write_handler(struct l_io *io, l_io_write_cb_t callback,
  262. void *user_data, l_io_destroy_cb_t destroy)
  263. {
  264. uint32_t events;
  265. int err;
  266. if (unlikely(!io || io->fd < 0))
  267. return false;
  268. l_util_debug(io->debug_handler, io->debug_data,
  269. "set write handler <%p>", io);
  270. if (io->write_handler == callback && io->write_destroy == destroy &&
  271. io->write_data == user_data)
  272. return true;
  273. if (io->write_destroy)
  274. io->write_destroy(io->write_data);
  275. if (callback)
  276. events = io->events | EPOLLOUT;
  277. else
  278. events = io->events & ~EPOLLOUT;
  279. io->write_handler = callback;
  280. io->write_destroy = destroy;
  281. io->write_data = user_data;
  282. if (events == io->events)
  283. return true;
  284. err = watch_modify(io->fd, events, false);
  285. if (err)
  286. return false;
  287. io->events = events;
  288. return true;
  289. }
  290. /**
  291. * l_io_set_disconnect_handler:
  292. * @io: IO object
  293. * @callback: disconnect handler callback function
  294. * @user_data: user data provided to disconnect handler callback function
  295. * @destroy: destroy function for user data
  296. *
  297. * Set disconnect function.
  298. *
  299. * Returns: #true on success and #false on failure
  300. **/
  301. LIB_EXPORT bool l_io_set_disconnect_handler(struct l_io *io,
  302. l_io_disconnect_cb_t callback,
  303. void *user_data, l_io_destroy_cb_t destroy)
  304. {
  305. if (unlikely(!io || io->fd < 0))
  306. return false;
  307. l_util_debug(io->debug_handler, io->debug_data,
  308. "set disconnect handler <%p>", io);
  309. if (io->disconnect_destroy)
  310. io->disconnect_destroy(io->disconnect_data);
  311. io->disconnect_handler = callback;
  312. io->disconnect_destroy = destroy;
  313. io->disconnect_data = user_data;
  314. return true;
  315. }
  316. /**
  317. * l_io_set_debug:
  318. * @io: IO object
  319. * @callback: debug callback function
  320. * @user_data: user data provided to debug callback function
  321. * @destroy: destroy function for user data
  322. *
  323. * Set debug function.
  324. *
  325. * Returns: #true on success and #false on failure
  326. **/
  327. LIB_EXPORT bool l_io_set_debug(struct l_io *io, l_io_debug_cb_t callback,
  328. void *user_data, l_io_destroy_cb_t destroy)
  329. {
  330. if (unlikely(!io))
  331. return false;
  332. if (io->debug_destroy)
  333. io->debug_destroy(io->debug_data);
  334. io->debug_handler = callback;
  335. io->debug_destroy = destroy;
  336. io->debug_data = user_data;
  337. return true;
  338. }