main.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  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. #define _GNU_SOURCE
  26. #include <errno.h>
  27. #include <unistd.h>
  28. #include <stdlib.h>
  29. #include <stddef.h>
  30. #include <limits.h>
  31. #include <signal.h>
  32. #include <sys/epoll.h>
  33. #include <sys/socket.h>
  34. #include <sys/un.h>
  35. #include "signal.h"
  36. #include "queue.h"
  37. #include "log.h"
  38. #include "useful.h"
  39. #include "main.h"
  40. #include "main-private.h"
  41. #include "private.h"
  42. #include "timeout.h"
  43. /**
  44. * SECTION:main
  45. * @short_description: Main loop handling
  46. *
  47. * Main loop handling
  48. */
  49. #define MAX_EPOLL_EVENTS 10
  50. #define IDLE_FLAG_DISPATCHING 1
  51. #define IDLE_FLAG_DESTROYED 2
  52. #define WATCH_FLAG_DISPATCHING 1
  53. #define WATCH_FLAG_DESTROYED 2
  54. #define WATCHDOG_TRIGGER_FREQ 2
  55. static int epoll_fd;
  56. static bool epoll_running;
  57. static bool epoll_terminate;
  58. static int idle_id;
  59. static int notify_fd;
  60. static struct l_timeout *watchdog;
  61. static struct l_queue *idle_list;
  62. struct watch_data {
  63. int fd;
  64. uint32_t events;
  65. uint32_t flags;
  66. watch_event_cb_t callback;
  67. watch_destroy_cb_t destroy;
  68. void *user_data;
  69. };
  70. #define DEFAULT_WATCH_ENTRIES 128
  71. static unsigned int watch_entries;
  72. static struct watch_data **watch_list;
  73. struct idle_data {
  74. idle_event_cb_t callback;
  75. idle_destroy_cb_t destroy;
  76. void *user_data;
  77. uint32_t flags;
  78. int id;
  79. };
  80. static inline bool __attribute__ ((always_inline)) create_epoll(void)
  81. {
  82. unsigned int i;
  83. epoll_fd = epoll_create1(EPOLL_CLOEXEC);
  84. if (epoll_fd < 0) {
  85. epoll_fd = 0;
  86. return false;
  87. }
  88. watch_list = malloc(DEFAULT_WATCH_ENTRIES * sizeof(void *));
  89. if (!watch_list)
  90. goto close_epoll;
  91. idle_list = l_queue_new();
  92. idle_id = 0;
  93. watch_entries = DEFAULT_WATCH_ENTRIES;
  94. for (i = 0; i < watch_entries; i++)
  95. watch_list[i] = NULL;
  96. return true;
  97. close_epoll:
  98. close(epoll_fd);
  99. epoll_fd = 0;
  100. return false;
  101. }
  102. int watch_add(int fd, uint32_t events, watch_event_cb_t callback,
  103. void *user_data, watch_destroy_cb_t destroy)
  104. {
  105. struct watch_data *data;
  106. struct epoll_event ev;
  107. int err;
  108. if (unlikely(fd < 0 || !callback))
  109. return -EINVAL;
  110. if (!epoll_fd)
  111. return -EIO;
  112. if ((unsigned int) fd > watch_entries - 1)
  113. return -ERANGE;
  114. data = l_new(struct watch_data, 1);
  115. data->fd = fd;
  116. data->events = events;
  117. data->flags = 0;
  118. data->callback = callback;
  119. data->destroy = destroy;
  120. data->user_data = user_data;
  121. memset(&ev, 0, sizeof(ev));
  122. ev.events = events;
  123. ev.data.ptr = data;
  124. err = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, data->fd, &ev);
  125. if (err < 0) {
  126. l_free(data);
  127. return -errno;
  128. }
  129. watch_list[fd] = data;
  130. return 0;
  131. }
  132. int watch_modify(int fd, uint32_t events, bool force)
  133. {
  134. struct watch_data *data;
  135. struct epoll_event ev;
  136. int err;
  137. if (unlikely(fd < 0))
  138. return -EINVAL;
  139. if ((unsigned int) fd > watch_entries - 1)
  140. return -ERANGE;
  141. data = watch_list[fd];
  142. if (!data)
  143. return -ENXIO;
  144. if (data->events == events && !force)
  145. return 0;
  146. memset(&ev, 0, sizeof(ev));
  147. ev.events = events;
  148. ev.data.ptr = data;
  149. err = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, data->fd, &ev);
  150. if (err < 0)
  151. return -errno;
  152. data->events = events;
  153. return 0;
  154. }
  155. int watch_clear(int fd)
  156. {
  157. struct watch_data *data;
  158. if (unlikely(fd < 0))
  159. return -EINVAL;
  160. if ((unsigned int) fd > watch_entries - 1)
  161. return -ERANGE;
  162. data = watch_list[fd];
  163. if (!data)
  164. return -ENXIO;
  165. watch_list[fd] = NULL;
  166. if (data->destroy)
  167. data->destroy(data->user_data);
  168. if (data->flags & WATCH_FLAG_DISPATCHING)
  169. data->flags |= WATCH_FLAG_DESTROYED;
  170. else
  171. l_free(data);
  172. return 0;
  173. }
  174. int watch_remove(int fd, bool epoll_del)
  175. {
  176. int err = watch_clear(fd);
  177. if (err < 0)
  178. return err;
  179. if (!epoll_del)
  180. goto done;
  181. err = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
  182. if (err < 0)
  183. return -errno;
  184. done:
  185. return err;
  186. }
  187. static bool idle_remove_by_id(void *data, void *user_data)
  188. {
  189. struct idle_data *idle = data;
  190. int id = L_PTR_TO_INT(user_data);
  191. if (idle->id != id)
  192. return false;
  193. if (idle->destroy)
  194. idle->destroy(idle->user_data);
  195. if (idle->flags & IDLE_FLAG_DISPATCHING) {
  196. idle->flags |= IDLE_FLAG_DESTROYED;
  197. return false;
  198. }
  199. l_free(idle);
  200. return true;
  201. }
  202. static bool idle_prune(void *data, void *user_data)
  203. {
  204. struct idle_data *idle = data;
  205. if ((idle->flags & IDLE_FLAG_DESTROYED) == 0)
  206. return false;
  207. l_free(idle);
  208. return true;
  209. }
  210. int idle_add(idle_event_cb_t callback, void *user_data, uint32_t flags,
  211. idle_destroy_cb_t destroy)
  212. {
  213. struct idle_data *data;
  214. if (unlikely(!callback))
  215. return -EINVAL;
  216. if (!epoll_fd)
  217. return -EIO;
  218. data = l_new(struct idle_data, 1);
  219. data->callback = callback;
  220. data->destroy = destroy;
  221. data->user_data = user_data;
  222. data->flags = flags;
  223. if (!l_queue_push_tail(idle_list, data)) {
  224. l_free(data);
  225. return -ENOMEM;
  226. }
  227. data->id = idle_id++;
  228. if (idle_id == INT_MAX)
  229. idle_id = 0;
  230. return data->id;
  231. }
  232. void idle_remove(int id)
  233. {
  234. l_queue_foreach_remove(idle_list, idle_remove_by_id,
  235. L_INT_TO_PTR(id));
  236. }
  237. static void idle_destroy(void *data)
  238. {
  239. struct idle_data *idle = data;
  240. if (!(idle->flags & IDLE_FLAG_NO_WARN_DANGLING))
  241. l_error("Dangling idle descriptor %p, %d found",
  242. data, idle->id);
  243. if (idle->destroy)
  244. idle->destroy(idle->user_data);
  245. l_free(idle);
  246. }
  247. static void idle_dispatch(void *data, void *user_data)
  248. {
  249. struct idle_data *idle = data;
  250. if (!idle->callback)
  251. return;
  252. idle->flags |= IDLE_FLAG_DISPATCHING;
  253. idle->callback(idle->user_data);
  254. idle->flags &= ~IDLE_FLAG_DISPATCHING;
  255. }
  256. static int sd_notify(const char *state)
  257. {
  258. int err;
  259. if (notify_fd <= 0)
  260. return -ENOTCONN;
  261. err = send(notify_fd, state, strlen(state), MSG_NOSIGNAL);
  262. if (err < 0)
  263. return -errno;
  264. return 0;
  265. }
  266. static void watchdog_callback(struct l_timeout *timeout, void *user_data)
  267. {
  268. int msec = L_PTR_TO_INT(user_data);
  269. sd_notify("WATCHDOG=1");
  270. l_timeout_modify_ms(timeout, msec);
  271. }
  272. static void create_sd_notify_socket(void)
  273. {
  274. const char *sock;
  275. struct sockaddr_un addr;
  276. const char *watchdog_usec;
  277. int msec;
  278. /* check if NOTIFY_SOCKET has been set */
  279. sock = getenv("NOTIFY_SOCKET");
  280. if (!sock)
  281. return;
  282. /* check for abstract socket or absolute path */
  283. if (sock[0] != '@' && sock[0] != '/')
  284. return;
  285. notify_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  286. if (notify_fd < 0) {
  287. notify_fd = 0;
  288. return;
  289. }
  290. memset(&addr, 0, sizeof(addr));
  291. addr.sun_family = AF_UNIX;
  292. strncpy(addr.sun_path, sock, sizeof(addr.sun_path) - 1);
  293. if (addr.sun_path[0] == '@')
  294. addr.sun_path[0] = '\0';
  295. if (bind(notify_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  296. close(notify_fd);
  297. notify_fd = 0;
  298. return;
  299. }
  300. watchdog_usec = getenv("WATCHDOG_USEC");
  301. if (!watchdog_usec)
  302. return;
  303. msec = atoi(watchdog_usec) / 1000;
  304. if (msec < WATCHDOG_TRIGGER_FREQ)
  305. return;
  306. msec /= WATCHDOG_TRIGGER_FREQ;
  307. watchdog = l_timeout_create_ms(msec, watchdog_callback,
  308. L_INT_TO_PTR(msec), NULL);
  309. }
  310. /**
  311. * l_main_init:
  312. *
  313. * Initialize the main loop. This must be called before l_main_run()
  314. * and any other function that directly or indirectly sets up an idle
  315. * or watch. A safe rule-of-thumb is to call it before any function
  316. * prefixed with "l_".
  317. *
  318. * Returns: true if initialization was successful, false otherwise.
  319. **/
  320. LIB_EXPORT bool l_main_init(void)
  321. {
  322. if (unlikely(epoll_running))
  323. return false;
  324. if (!create_epoll())
  325. return false;
  326. create_sd_notify_socket();
  327. epoll_terminate = false;
  328. return true;
  329. }
  330. /**
  331. * l_main_prepare:
  332. *
  333. * Prepare the iteration of the main loop
  334. *
  335. * Returns: The timeout to use. This will be 0 if idle-event processing is
  336. * currently pending, or -1 otherwise. This value can be used to pass to
  337. * l_main_iterate.
  338. */
  339. LIB_EXPORT int l_main_prepare(void)
  340. {
  341. return l_queue_isempty(idle_list) ? -1 : 0;
  342. }
  343. /**
  344. * l_main_iterate:
  345. *
  346. * Run one iteration of the main event loop
  347. */
  348. LIB_EXPORT void l_main_iterate(int timeout)
  349. {
  350. struct epoll_event events[MAX_EPOLL_EVENTS];
  351. struct watch_data *data;
  352. int n, nfds;
  353. nfds = epoll_wait(epoll_fd, events, MAX_EPOLL_EVENTS, timeout);
  354. for (n = 0; n < nfds; n++) {
  355. data = events[n].data.ptr;
  356. data->flags |= WATCH_FLAG_DISPATCHING;
  357. }
  358. for (n = 0; n < nfds; n++) {
  359. data = events[n].data.ptr;
  360. if (data->flags & WATCH_FLAG_DESTROYED)
  361. continue;
  362. data->callback(data->fd, events[n].events,
  363. data->user_data);
  364. }
  365. for (n = 0; n < nfds; n++) {
  366. data = events[n].data.ptr;
  367. if (data->flags & WATCH_FLAG_DESTROYED)
  368. l_free(data);
  369. else
  370. data->flags = 0;
  371. }
  372. l_queue_foreach(idle_list, idle_dispatch, NULL);
  373. l_queue_foreach_remove(idle_list, idle_prune, NULL);
  374. }
  375. /**
  376. * l_main_run:
  377. *
  378. * Run the main loop
  379. *
  380. * The loop may be restarted by invoking this function after a
  381. * previous invocation returns, provided that l_main_exit() has not
  382. * been called first.
  383. *
  384. * Returns: #EXIT_SUCCESS after successful execution or #EXIT_FAILURE in
  385. * case of failure
  386. **/
  387. LIB_EXPORT int l_main_run(void)
  388. {
  389. int timeout;
  390. /* Has l_main_init() been called? */
  391. if (unlikely(!epoll_fd))
  392. return EXIT_FAILURE;
  393. if (unlikely(epoll_running))
  394. return EXIT_FAILURE;
  395. epoll_running = true;
  396. for (;;) {
  397. if (epoll_terminate)
  398. break;
  399. timeout = l_main_prepare();
  400. l_main_iterate(timeout);
  401. }
  402. epoll_running = false;
  403. if (notify_fd) {
  404. close(notify_fd);
  405. notify_fd = 0;
  406. l_timeout_remove(watchdog);
  407. watchdog = NULL;
  408. }
  409. return EXIT_SUCCESS;
  410. }
  411. /**
  412. * l_main_exit:
  413. *
  414. * Clean up after main loop completes.
  415. *
  416. **/
  417. LIB_EXPORT bool l_main_exit(void)
  418. {
  419. unsigned int i;
  420. if (epoll_running) {
  421. l_error("Cleanup attempted on running main loop");
  422. return false;
  423. }
  424. for (i = 0; i < watch_entries; i++) {
  425. struct watch_data *data = watch_list[i];
  426. if (!data)
  427. continue;
  428. epoll_ctl(epoll_fd, EPOLL_CTL_DEL, data->fd, NULL);
  429. if (data->destroy)
  430. data->destroy(data->user_data);
  431. else
  432. l_error("Dangling file descriptor %d found", data->fd);
  433. l_free(data);
  434. }
  435. watch_entries = 0;
  436. free(watch_list);
  437. watch_list = NULL;
  438. l_queue_destroy(idle_list, idle_destroy);
  439. idle_list = NULL;
  440. close(epoll_fd);
  441. epoll_fd = 0;
  442. return true;
  443. }
  444. /**
  445. * l_main_quit:
  446. *
  447. * Teminate the running main loop
  448. *
  449. * Returns: #true when terminating the main loop or #false in case of failure
  450. **/
  451. LIB_EXPORT bool l_main_quit(void)
  452. {
  453. if (unlikely(!epoll_running))
  454. return false;
  455. epoll_terminate = true;
  456. return true;
  457. }
  458. struct signal_data {
  459. l_main_signal_cb_t callback;
  460. void *user_data;
  461. };
  462. static void sigint_handler(void *user_data)
  463. {
  464. struct signal_data *data = user_data;
  465. if (data->callback)
  466. data->callback(SIGINT, data->user_data);
  467. }
  468. static void sigterm_handler(void *user_data)
  469. {
  470. struct signal_data *data = user_data;
  471. if (data->callback)
  472. data->callback(SIGTERM, data->user_data);
  473. }
  474. /**
  475. * l_main_run_with_signal:
  476. *
  477. * Run the main loop with signal handling for SIGINT and SIGTERM
  478. *
  479. * Returns: #EXIT_SUCCESS after successful execution or #EXIT_FAILURE in
  480. * case of failure
  481. **/
  482. LIB_EXPORT int l_main_run_with_signal(l_main_signal_cb_t callback,
  483. void *user_data)
  484. {
  485. struct signal_data *data;
  486. struct l_signal *sigint;
  487. struct l_signal *sigterm;
  488. int result;
  489. data = l_new(struct signal_data, 1);
  490. data->callback = callback;
  491. data->user_data = user_data;
  492. sigint = l_signal_create(SIGINT, sigint_handler, data, NULL);
  493. sigterm = l_signal_create(SIGTERM, sigterm_handler, data, NULL);
  494. result = l_main_run();
  495. l_signal_remove(sigint);
  496. l_signal_remove(sigterm);
  497. l_free(data);
  498. return result;
  499. }
  500. /**
  501. * l_main_get_epoll_fd:
  502. *
  503. * Can be used to obtain the epoll file descriptor in order to integrate
  504. * the ell main event loop with other event loops.
  505. *
  506. * Returns: epoll file descriptor
  507. **/
  508. LIB_EXPORT int l_main_get_epoll_fd(void)
  509. {
  510. return epoll_fd;
  511. }