eloop_none.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /*
  2. * Event loop - empty template (basic structure, but no OS specific operations)
  3. * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include "common.h"
  10. #include "list.h"
  11. #include "eloop.h"
  12. struct eloop_sock {
  13. int sock;
  14. void *eloop_data;
  15. void *user_data;
  16. eloop_sock_handler handler;
  17. };
  18. struct eloop_timeout {
  19. struct dl_list list;
  20. struct os_time time;
  21. void *eloop_data;
  22. void *user_data;
  23. eloop_timeout_handler handler;
  24. };
  25. struct eloop_signal {
  26. int sig;
  27. void *user_data;
  28. eloop_signal_handler handler;
  29. int signaled;
  30. };
  31. struct eloop_data {
  32. int max_sock, reader_count;
  33. struct eloop_sock *readers;
  34. struct dl_list timeout;
  35. int signal_count;
  36. struct eloop_signal *signals;
  37. int signaled;
  38. int pending_terminate;
  39. int terminate;
  40. int reader_table_changed;
  41. };
  42. static struct eloop_data eloop;
  43. int eloop_init(void)
  44. {
  45. memset(&eloop, 0, sizeof(eloop));
  46. dl_list_init(&eloop.timeout);
  47. return 0;
  48. }
  49. int eloop_register_read_sock(int sock, eloop_sock_handler handler,
  50. void *eloop_data, void *user_data)
  51. {
  52. struct eloop_sock *tmp;
  53. tmp = (struct eloop_sock *)
  54. realloc(eloop.readers,
  55. (eloop.reader_count + 1) * sizeof(struct eloop_sock));
  56. if (tmp == NULL)
  57. return -1;
  58. tmp[eloop.reader_count].sock = sock;
  59. tmp[eloop.reader_count].eloop_data = eloop_data;
  60. tmp[eloop.reader_count].user_data = user_data;
  61. tmp[eloop.reader_count].handler = handler;
  62. eloop.reader_count++;
  63. eloop.readers = tmp;
  64. if (sock > eloop.max_sock)
  65. eloop.max_sock = sock;
  66. eloop.reader_table_changed = 1;
  67. return 0;
  68. }
  69. void eloop_unregister_read_sock(int sock)
  70. {
  71. int i;
  72. if (eloop.readers == NULL || eloop.reader_count == 0)
  73. return;
  74. for (i = 0; i < eloop.reader_count; i++) {
  75. if (eloop.readers[i].sock == sock)
  76. break;
  77. }
  78. if (i == eloop.reader_count)
  79. return;
  80. if (i != eloop.reader_count - 1) {
  81. memmove(&eloop.readers[i], &eloop.readers[i + 1],
  82. (eloop.reader_count - i - 1) *
  83. sizeof(struct eloop_sock));
  84. }
  85. eloop.reader_count--;
  86. eloop.reader_table_changed = 1;
  87. }
  88. int eloop_register_timeout(unsigned int secs, unsigned int usecs,
  89. eloop_timeout_handler handler,
  90. void *eloop_data, void *user_data)
  91. {
  92. struct eloop_timeout *timeout, *tmp;
  93. timeout = (struct eloop_timeout *) malloc(sizeof(*timeout));
  94. if (timeout == NULL)
  95. return -1;
  96. os_get_time(&timeout->time);
  97. timeout->time.sec += secs;
  98. timeout->time.usec += usecs;
  99. while (timeout->time.usec >= 1000000) {
  100. timeout->time.sec++;
  101. timeout->time.usec -= 1000000;
  102. }
  103. timeout->eloop_data = eloop_data;
  104. timeout->user_data = user_data;
  105. timeout->handler = handler;
  106. /* Maintain timeouts in order of increasing time */
  107. dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
  108. if (os_time_before(&timeout->time, &tmp->time)) {
  109. dl_list_add(tmp->list.prev, &timeout->list);
  110. return 0;
  111. }
  112. }
  113. dl_list_add_tail(&eloop.timeout, &timeout->list);
  114. return 0;
  115. }
  116. int eloop_cancel_timeout(eloop_timeout_handler handler,
  117. void *eloop_data, void *user_data)
  118. {
  119. struct eloop_timeout *timeout, *prev;
  120. int removed = 0;
  121. dl_list_for_each_safe(timeout, prev, &eloop.timeout,
  122. struct eloop_timeout, list) {
  123. if (timeout->handler == handler &&
  124. (timeout->eloop_data == eloop_data ||
  125. eloop_data == ELOOP_ALL_CTX) &&
  126. (timeout->user_data == user_data ||
  127. user_data == ELOOP_ALL_CTX)) {
  128. dl_list_del(&timeout->list);
  129. free(timeout);
  130. removed++;
  131. }
  132. }
  133. return removed;
  134. }
  135. int eloop_is_timeout_registered(eloop_timeout_handler handler,
  136. void *eloop_data, void *user_data)
  137. {
  138. struct eloop_timeout *tmp;
  139. dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
  140. if (tmp->handler == handler &&
  141. tmp->eloop_data == eloop_data &&
  142. tmp->user_data == user_data)
  143. return 1;
  144. }
  145. return 0;
  146. }
  147. /* TODO: replace with suitable signal handler */
  148. #if 0
  149. static void eloop_handle_signal(int sig)
  150. {
  151. int i;
  152. eloop.signaled++;
  153. for (i = 0; i < eloop.signal_count; i++) {
  154. if (eloop.signals[i].sig == sig) {
  155. eloop.signals[i].signaled++;
  156. break;
  157. }
  158. }
  159. }
  160. #endif
  161. static void eloop_process_pending_signals(void)
  162. {
  163. int i;
  164. if (eloop.signaled == 0)
  165. return;
  166. eloop.signaled = 0;
  167. if (eloop.pending_terminate) {
  168. eloop.pending_terminate = 0;
  169. }
  170. for (i = 0; i < eloop.signal_count; i++) {
  171. if (eloop.signals[i].signaled) {
  172. eloop.signals[i].signaled = 0;
  173. eloop.signals[i].handler(eloop.signals[i].sig,
  174. eloop.signals[i].user_data);
  175. }
  176. }
  177. }
  178. int eloop_register_signal(int sig, eloop_signal_handler handler,
  179. void *user_data)
  180. {
  181. struct eloop_signal *tmp;
  182. tmp = (struct eloop_signal *)
  183. realloc(eloop.signals,
  184. (eloop.signal_count + 1) *
  185. sizeof(struct eloop_signal));
  186. if (tmp == NULL)
  187. return -1;
  188. tmp[eloop.signal_count].sig = sig;
  189. tmp[eloop.signal_count].user_data = user_data;
  190. tmp[eloop.signal_count].handler = handler;
  191. tmp[eloop.signal_count].signaled = 0;
  192. eloop.signal_count++;
  193. eloop.signals = tmp;
  194. /* TODO: register signal handler */
  195. return 0;
  196. }
  197. int eloop_register_signal_terminate(eloop_signal_handler handler,
  198. void *user_data)
  199. {
  200. #if 0
  201. /* TODO: for example */
  202. int ret = eloop_register_signal(SIGINT, handler, user_data);
  203. if (ret == 0)
  204. ret = eloop_register_signal(SIGTERM, handler, user_data);
  205. return ret;
  206. #endif
  207. return 0;
  208. }
  209. int eloop_register_signal_reconfig(eloop_signal_handler handler,
  210. void *user_data)
  211. {
  212. #if 0
  213. /* TODO: for example */
  214. return eloop_register_signal(SIGHUP, handler, user_data);
  215. #endif
  216. return 0;
  217. }
  218. void eloop_run(void)
  219. {
  220. int i;
  221. struct os_time tv, now;
  222. while (!eloop.terminate &&
  223. (!dl_list_empty(&eloop.timeout) || eloop.reader_count > 0)) {
  224. struct eloop_timeout *timeout;
  225. timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
  226. list);
  227. if (timeout) {
  228. os_get_time(&now);
  229. if (os_time_before(&now, &timeout->time))
  230. os_time_sub(&timeout->time, &now, &tv);
  231. else
  232. tv.sec = tv.usec = 0;
  233. }
  234. /*
  235. * TODO: wait for any event (read socket ready, timeout (tv),
  236. * signal
  237. */
  238. os_sleep(1, 0); /* just a dummy wait for testing */
  239. eloop_process_pending_signals();
  240. /* check if some registered timeouts have occurred */
  241. timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
  242. list);
  243. if (timeout) {
  244. os_get_time(&now);
  245. if (!os_time_before(&now, &timeout->time)) {
  246. dl_list_del(&timeout->list);
  247. timeout->handler(timeout->eloop_data,
  248. timeout->user_data);
  249. free(timeout);
  250. }
  251. }
  252. eloop.reader_table_changed = 0;
  253. for (i = 0; i < eloop.reader_count; i++) {
  254. /*
  255. * TODO: call each handler that has pending data to
  256. * read
  257. */
  258. if (0 /* TODO: eloop.readers[i].sock ready */) {
  259. eloop.readers[i].handler(
  260. eloop.readers[i].sock,
  261. eloop.readers[i].eloop_data,
  262. eloop.readers[i].user_data);
  263. if (eloop.reader_table_changed)
  264. break;
  265. }
  266. }
  267. }
  268. }
  269. void eloop_terminate(void)
  270. {
  271. eloop.terminate = 1;
  272. }
  273. void eloop_destroy(void)
  274. {
  275. struct eloop_timeout *timeout, *prev;
  276. dl_list_for_each_safe(timeout, prev, &eloop.timeout,
  277. struct eloop_timeout, list) {
  278. dl_list_del(&timeout->list);
  279. free(timeout);
  280. }
  281. free(eloop.readers);
  282. free(eloop.signals);
  283. }
  284. int eloop_terminated(void)
  285. {
  286. return eloop.terminate;
  287. }
  288. void eloop_wait_for_read_sock(int sock)
  289. {
  290. /*
  291. * TODO: wait for the file descriptor to have something available for
  292. * reading
  293. */
  294. }