eloop.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. /*
  2. * Event loop based on select() loop
  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 <assert.h>
  10. #include "common.h"
  11. #include "trace.h"
  12. #include "list.h"
  13. #include "eloop.h"
  14. #if defined(CONFIG_ELOOP_POLL) && defined(CONFIG_ELOOP_EPOLL)
  15. #error Do not define both of poll and epoll
  16. #endif
  17. #if !defined(CONFIG_ELOOP_POLL) && !defined(CONFIG_ELOOP_EPOLL)
  18. #define CONFIG_ELOOP_SELECT
  19. #endif
  20. #ifdef CONFIG_ELOOP_POLL
  21. #include <poll.h>
  22. #endif /* CONFIG_ELOOP_POLL */
  23. #ifdef CONFIG_ELOOP_EPOLL
  24. #include <sys/epoll.h>
  25. #endif /* CONFIG_ELOOP_EPOLL */
  26. struct eloop_sock {
  27. int sock;
  28. void *eloop_data;
  29. void *user_data;
  30. eloop_sock_handler handler;
  31. WPA_TRACE_REF(eloop);
  32. WPA_TRACE_REF(user);
  33. WPA_TRACE_INFO
  34. };
  35. struct eloop_timeout {
  36. struct dl_list list;
  37. struct os_reltime time;
  38. void *eloop_data;
  39. void *user_data;
  40. eloop_timeout_handler handler;
  41. WPA_TRACE_REF(eloop);
  42. WPA_TRACE_REF(user);
  43. WPA_TRACE_INFO
  44. };
  45. struct eloop_signal {
  46. int sig;
  47. void *user_data;
  48. eloop_signal_handler handler;
  49. int signaled;
  50. };
  51. struct eloop_sock_table {
  52. int count;
  53. struct eloop_sock *table;
  54. #ifdef CONFIG_ELOOP_EPOLL
  55. eloop_event_type type;
  56. #else /* CONFIG_ELOOP_EPOLL */
  57. int changed;
  58. #endif /* CONFIG_ELOOP_EPOLL */
  59. };
  60. struct eloop_data {
  61. int max_sock;
  62. int count; /* sum of all table counts */
  63. #ifdef CONFIG_ELOOP_POLL
  64. int max_pollfd_map; /* number of pollfds_map currently allocated */
  65. int max_poll_fds; /* number of pollfds currently allocated */
  66. struct pollfd *pollfds;
  67. struct pollfd **pollfds_map;
  68. #endif /* CONFIG_ELOOP_POLL */
  69. #ifdef CONFIG_ELOOP_EPOLL
  70. int epollfd;
  71. int epoll_max_event_num;
  72. int epoll_max_fd;
  73. struct eloop_sock *epoll_table;
  74. struct epoll_event *epoll_events;
  75. #endif /* CONFIG_ELOOP_EPOLL */
  76. struct eloop_sock_table readers;
  77. struct eloop_sock_table writers;
  78. struct eloop_sock_table exceptions;
  79. struct dl_list timeout;
  80. int signal_count;
  81. struct eloop_signal *signals;
  82. int signaled;
  83. int pending_terminate;
  84. int terminate;
  85. };
  86. static struct eloop_data eloop;
  87. #ifdef WPA_TRACE
  88. static void eloop_sigsegv_handler(int sig)
  89. {
  90. wpa_trace_show("eloop SIGSEGV");
  91. abort();
  92. }
  93. static void eloop_trace_sock_add_ref(struct eloop_sock_table *table)
  94. {
  95. int i;
  96. if (table == NULL || table->table == NULL)
  97. return;
  98. for (i = 0; i < table->count; i++) {
  99. wpa_trace_add_ref(&table->table[i], eloop,
  100. table->table[i].eloop_data);
  101. wpa_trace_add_ref(&table->table[i], user,
  102. table->table[i].user_data);
  103. }
  104. }
  105. static void eloop_trace_sock_remove_ref(struct eloop_sock_table *table)
  106. {
  107. int i;
  108. if (table == NULL || table->table == NULL)
  109. return;
  110. for (i = 0; i < table->count; i++) {
  111. wpa_trace_remove_ref(&table->table[i], eloop,
  112. table->table[i].eloop_data);
  113. wpa_trace_remove_ref(&table->table[i], user,
  114. table->table[i].user_data);
  115. }
  116. }
  117. #else /* WPA_TRACE */
  118. #define eloop_trace_sock_add_ref(table) do { } while (0)
  119. #define eloop_trace_sock_remove_ref(table) do { } while (0)
  120. #endif /* WPA_TRACE */
  121. int eloop_init(void)
  122. {
  123. os_memset(&eloop, 0, sizeof(eloop));
  124. dl_list_init(&eloop.timeout);
  125. #ifdef CONFIG_ELOOP_EPOLL
  126. eloop.epollfd = epoll_create1(0);
  127. if (eloop.epollfd < 0) {
  128. wpa_printf(MSG_ERROR, "%s: epoll_create1 failed. %s\n",
  129. __func__, strerror(errno));
  130. return -1;
  131. }
  132. eloop.readers.type = EVENT_TYPE_READ;
  133. eloop.writers.type = EVENT_TYPE_WRITE;
  134. eloop.exceptions.type = EVENT_TYPE_EXCEPTION;
  135. #endif /* CONFIG_ELOOP_EPOLL */
  136. #ifdef WPA_TRACE
  137. signal(SIGSEGV, eloop_sigsegv_handler);
  138. #endif /* WPA_TRACE */
  139. return 0;
  140. }
  141. static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
  142. int sock, eloop_sock_handler handler,
  143. void *eloop_data, void *user_data)
  144. {
  145. #ifdef CONFIG_ELOOP_EPOLL
  146. struct eloop_sock *temp_table;
  147. struct epoll_event ev, *temp_events;
  148. int next;
  149. #endif /* CONFIG_ELOOP_EPOLL */
  150. struct eloop_sock *tmp;
  151. int new_max_sock;
  152. if (sock > eloop.max_sock)
  153. new_max_sock = sock;
  154. else
  155. new_max_sock = eloop.max_sock;
  156. if (table == NULL)
  157. return -1;
  158. #ifdef CONFIG_ELOOP_POLL
  159. if (new_max_sock >= eloop.max_pollfd_map) {
  160. struct pollfd **nmap;
  161. nmap = os_realloc_array(eloop.pollfds_map, new_max_sock + 50,
  162. sizeof(struct pollfd *));
  163. if (nmap == NULL)
  164. return -1;
  165. eloop.max_pollfd_map = new_max_sock + 50;
  166. eloop.pollfds_map = nmap;
  167. }
  168. if (eloop.count + 1 > eloop.max_poll_fds) {
  169. struct pollfd *n;
  170. int nmax = eloop.count + 1 + 50;
  171. n = os_realloc_array(eloop.pollfds, nmax,
  172. sizeof(struct pollfd));
  173. if (n == NULL)
  174. return -1;
  175. eloop.max_poll_fds = nmax;
  176. eloop.pollfds = n;
  177. }
  178. #endif /* CONFIG_ELOOP_POLL */
  179. #ifdef CONFIG_ELOOP_EPOLL
  180. if (new_max_sock >= eloop.epoll_max_fd) {
  181. next = eloop.epoll_max_fd == 0 ? 16 : eloop.epoll_max_fd * 2;
  182. temp_table = os_realloc_array(eloop.epoll_table, next,
  183. sizeof(struct eloop_sock));
  184. if (temp_table == NULL)
  185. return -1;
  186. eloop.epoll_max_fd = next;
  187. eloop.epoll_table = temp_table;
  188. }
  189. if (eloop.count + 1 > eloop.epoll_max_event_num) {
  190. next = eloop.epoll_max_event_num == 0 ? 8 :
  191. eloop.epoll_max_event_num * 2;
  192. temp_events = os_realloc_array(eloop.epoll_events, next,
  193. sizeof(struct epoll_event));
  194. if (temp_events == NULL) {
  195. wpa_printf(MSG_ERROR, "%s: malloc for epoll failed. "
  196. "%s\n", __func__, strerror(errno));
  197. return -1;
  198. }
  199. eloop.epoll_max_event_num = next;
  200. eloop.epoll_events = temp_events;
  201. }
  202. #endif /* CONFIG_ELOOP_EPOLL */
  203. eloop_trace_sock_remove_ref(table);
  204. tmp = os_realloc_array(table->table, table->count + 1,
  205. sizeof(struct eloop_sock));
  206. if (tmp == NULL)
  207. return -1;
  208. tmp[table->count].sock = sock;
  209. tmp[table->count].eloop_data = eloop_data;
  210. tmp[table->count].user_data = user_data;
  211. tmp[table->count].handler = handler;
  212. wpa_trace_record(&tmp[table->count]);
  213. table->count++;
  214. table->table = tmp;
  215. eloop.max_sock = new_max_sock;
  216. eloop.count++;
  217. #ifndef CONFIG_ELOOP_EPOLL
  218. table->changed = 1;
  219. #endif /* CONFIG_ELOOP_EPOLL */
  220. eloop_trace_sock_add_ref(table);
  221. #ifdef CONFIG_ELOOP_EPOLL
  222. os_memset(&ev, 0, sizeof(ev));
  223. switch (table->type) {
  224. case EVENT_TYPE_READ:
  225. ev.events = EPOLLIN;
  226. break;
  227. case EVENT_TYPE_WRITE:
  228. ev.events = EPOLLOUT;
  229. break;
  230. /*
  231. * Exceptions are always checked when using epoll, but I suppose it's
  232. * possible that someone registered a socket *only* for exception
  233. * handling.
  234. */
  235. case EVENT_TYPE_EXCEPTION:
  236. ev.events = EPOLLERR | EPOLLHUP;
  237. break;
  238. }
  239. ev.data.fd = sock;
  240. if (epoll_ctl(eloop.epollfd, EPOLL_CTL_ADD, sock, &ev) < 0) {
  241. wpa_printf(MSG_ERROR, "%s: epoll_ctl(ADD) for fd=%d "
  242. "failed. %s\n", __func__, sock, strerror(errno));
  243. return -1;
  244. }
  245. os_memcpy(&eloop.epoll_table[sock], &table->table[table->count - 1],
  246. sizeof(struct eloop_sock));
  247. #endif /* CONFIG_ELOOP_EPOLL */
  248. return 0;
  249. }
  250. static void eloop_sock_table_remove_sock(struct eloop_sock_table *table,
  251. int sock)
  252. {
  253. int i;
  254. if (table == NULL || table->table == NULL || table->count == 0)
  255. return;
  256. for (i = 0; i < table->count; i++) {
  257. if (table->table[i].sock == sock)
  258. break;
  259. }
  260. if (i == table->count)
  261. return;
  262. eloop_trace_sock_remove_ref(table);
  263. if (i != table->count - 1) {
  264. os_memmove(&table->table[i], &table->table[i + 1],
  265. (table->count - i - 1) *
  266. sizeof(struct eloop_sock));
  267. }
  268. table->count--;
  269. eloop.count--;
  270. #ifndef CONFIG_ELOOP_EPOLL
  271. table->changed = 1;
  272. #endif /* CONFIG_ELOOP_EPOLL */
  273. eloop_trace_sock_add_ref(table);
  274. #ifdef CONFIG_ELOOP_EPOLL
  275. if (epoll_ctl(eloop.epollfd, EPOLL_CTL_DEL, sock, NULL) < 0) {
  276. wpa_printf(MSG_ERROR, "%s: epoll_ctl(DEL) for fd=%d "
  277. "failed. %s\n", __func__, sock, strerror(errno));
  278. return;
  279. }
  280. os_memset(&eloop.epoll_table[sock], 0, sizeof(struct eloop_sock));
  281. #endif /* CONFIG_ELOOP_EPOLL */
  282. }
  283. #ifdef CONFIG_ELOOP_POLL
  284. static struct pollfd * find_pollfd(struct pollfd **pollfds_map, int fd, int mx)
  285. {
  286. if (fd < mx && fd >= 0)
  287. return pollfds_map[fd];
  288. return NULL;
  289. }
  290. static int eloop_sock_table_set_fds(struct eloop_sock_table *readers,
  291. struct eloop_sock_table *writers,
  292. struct eloop_sock_table *exceptions,
  293. struct pollfd *pollfds,
  294. struct pollfd **pollfds_map,
  295. int max_pollfd_map)
  296. {
  297. int i;
  298. int nxt = 0;
  299. int fd;
  300. struct pollfd *pfd;
  301. /* Clear pollfd lookup map. It will be re-populated below. */
  302. os_memset(pollfds_map, 0, sizeof(struct pollfd *) * max_pollfd_map);
  303. if (readers && readers->table) {
  304. for (i = 0; i < readers->count; i++) {
  305. fd = readers->table[i].sock;
  306. assert(fd >= 0 && fd < max_pollfd_map);
  307. pollfds[nxt].fd = fd;
  308. pollfds[nxt].events = POLLIN;
  309. pollfds[nxt].revents = 0;
  310. pollfds_map[fd] = &(pollfds[nxt]);
  311. nxt++;
  312. }
  313. }
  314. if (writers && writers->table) {
  315. for (i = 0; i < writers->count; i++) {
  316. /*
  317. * See if we already added this descriptor, update it
  318. * if so.
  319. */
  320. fd = writers->table[i].sock;
  321. assert(fd >= 0 && fd < max_pollfd_map);
  322. pfd = pollfds_map[fd];
  323. if (!pfd) {
  324. pfd = &(pollfds[nxt]);
  325. pfd->events = 0;
  326. pfd->fd = fd;
  327. pollfds[i].revents = 0;
  328. pollfds_map[fd] = pfd;
  329. nxt++;
  330. }
  331. pfd->events |= POLLOUT;
  332. }
  333. }
  334. /*
  335. * Exceptions are always checked when using poll, but I suppose it's
  336. * possible that someone registered a socket *only* for exception
  337. * handling. Set the POLLIN bit in this case.
  338. */
  339. if (exceptions && exceptions->table) {
  340. for (i = 0; i < exceptions->count; i++) {
  341. /*
  342. * See if we already added this descriptor, just use it
  343. * if so.
  344. */
  345. fd = exceptions->table[i].sock;
  346. assert(fd >= 0 && fd < max_pollfd_map);
  347. pfd = pollfds_map[fd];
  348. if (!pfd) {
  349. pfd = &(pollfds[nxt]);
  350. pfd->events = POLLIN;
  351. pfd->fd = fd;
  352. pollfds[i].revents = 0;
  353. pollfds_map[fd] = pfd;
  354. nxt++;
  355. }
  356. }
  357. }
  358. return nxt;
  359. }
  360. static int eloop_sock_table_dispatch_table(struct eloop_sock_table *table,
  361. struct pollfd **pollfds_map,
  362. int max_pollfd_map,
  363. short int revents)
  364. {
  365. int i;
  366. struct pollfd *pfd;
  367. if (!table || !table->table)
  368. return 0;
  369. table->changed = 0;
  370. for (i = 0; i < table->count; i++) {
  371. pfd = find_pollfd(pollfds_map, table->table[i].sock,
  372. max_pollfd_map);
  373. if (!pfd)
  374. continue;
  375. if (!(pfd->revents & revents))
  376. continue;
  377. table->table[i].handler(table->table[i].sock,
  378. table->table[i].eloop_data,
  379. table->table[i].user_data);
  380. if (table->changed)
  381. return 1;
  382. }
  383. return 0;
  384. }
  385. static void eloop_sock_table_dispatch(struct eloop_sock_table *readers,
  386. struct eloop_sock_table *writers,
  387. struct eloop_sock_table *exceptions,
  388. struct pollfd **pollfds_map,
  389. int max_pollfd_map)
  390. {
  391. if (eloop_sock_table_dispatch_table(readers, pollfds_map,
  392. max_pollfd_map, POLLIN | POLLERR |
  393. POLLHUP))
  394. return; /* pollfds may be invalid at this point */
  395. if (eloop_sock_table_dispatch_table(writers, pollfds_map,
  396. max_pollfd_map, POLLOUT))
  397. return; /* pollfds may be invalid at this point */
  398. eloop_sock_table_dispatch_table(exceptions, pollfds_map,
  399. max_pollfd_map, POLLERR | POLLHUP);
  400. }
  401. #endif /* CONFIG_ELOOP_POLL */
  402. #ifdef CONFIG_ELOOP_SELECT
  403. static void eloop_sock_table_set_fds(struct eloop_sock_table *table,
  404. fd_set *fds)
  405. {
  406. int i;
  407. FD_ZERO(fds);
  408. if (table->table == NULL)
  409. return;
  410. for (i = 0; i < table->count; i++) {
  411. assert(table->table[i].sock >= 0);
  412. FD_SET(table->table[i].sock, fds);
  413. }
  414. }
  415. static void eloop_sock_table_dispatch(struct eloop_sock_table *table,
  416. fd_set *fds)
  417. {
  418. int i;
  419. if (table == NULL || table->table == NULL)
  420. return;
  421. table->changed = 0;
  422. for (i = 0; i < table->count; i++) {
  423. if (FD_ISSET(table->table[i].sock, fds)) {
  424. table->table[i].handler(table->table[i].sock,
  425. table->table[i].eloop_data,
  426. table->table[i].user_data);
  427. if (table->changed)
  428. break;
  429. }
  430. }
  431. }
  432. #endif /* CONFIG_ELOOP_SELECT */
  433. #ifdef CONFIG_ELOOP_EPOLL
  434. static void eloop_sock_table_dispatch(struct epoll_event *events, int nfds)
  435. {
  436. struct eloop_sock *table;
  437. int i;
  438. for (i = 0; i < nfds; i++) {
  439. table = &eloop.epoll_table[events[i].data.fd];
  440. if (table->handler == NULL)
  441. continue;
  442. table->handler(table->sock, table->eloop_data,
  443. table->user_data);
  444. }
  445. }
  446. #endif /* CONFIG_ELOOP_EPOLL */
  447. static void eloop_sock_table_destroy(struct eloop_sock_table *table)
  448. {
  449. if (table) {
  450. int i;
  451. for (i = 0; i < table->count && table->table; i++) {
  452. wpa_printf(MSG_INFO, "ELOOP: remaining socket: "
  453. "sock=%d eloop_data=%p user_data=%p "
  454. "handler=%p",
  455. table->table[i].sock,
  456. table->table[i].eloop_data,
  457. table->table[i].user_data,
  458. table->table[i].handler);
  459. wpa_trace_dump_funcname("eloop unregistered socket "
  460. "handler",
  461. table->table[i].handler);
  462. wpa_trace_dump("eloop sock", &table->table[i]);
  463. }
  464. os_free(table->table);
  465. }
  466. }
  467. int eloop_register_read_sock(int sock, eloop_sock_handler handler,
  468. void *eloop_data, void *user_data)
  469. {
  470. return eloop_register_sock(sock, EVENT_TYPE_READ, handler,
  471. eloop_data, user_data);
  472. }
  473. void eloop_unregister_read_sock(int sock)
  474. {
  475. eloop_unregister_sock(sock, EVENT_TYPE_READ);
  476. }
  477. static struct eloop_sock_table *eloop_get_sock_table(eloop_event_type type)
  478. {
  479. switch (type) {
  480. case EVENT_TYPE_READ:
  481. return &eloop.readers;
  482. case EVENT_TYPE_WRITE:
  483. return &eloop.writers;
  484. case EVENT_TYPE_EXCEPTION:
  485. return &eloop.exceptions;
  486. }
  487. return NULL;
  488. }
  489. int eloop_register_sock(int sock, eloop_event_type type,
  490. eloop_sock_handler handler,
  491. void *eloop_data, void *user_data)
  492. {
  493. struct eloop_sock_table *table;
  494. assert(sock >= 0);
  495. table = eloop_get_sock_table(type);
  496. return eloop_sock_table_add_sock(table, sock, handler,
  497. eloop_data, user_data);
  498. }
  499. void eloop_unregister_sock(int sock, eloop_event_type type)
  500. {
  501. struct eloop_sock_table *table;
  502. table = eloop_get_sock_table(type);
  503. eloop_sock_table_remove_sock(table, sock);
  504. }
  505. int eloop_register_timeout(unsigned int secs, unsigned int usecs,
  506. eloop_timeout_handler handler,
  507. void *eloop_data, void *user_data)
  508. {
  509. struct eloop_timeout *timeout, *tmp;
  510. os_time_t now_sec;
  511. timeout = os_zalloc(sizeof(*timeout));
  512. if (timeout == NULL)
  513. return -1;
  514. if (os_get_reltime(&timeout->time) < 0) {
  515. os_free(timeout);
  516. return -1;
  517. }
  518. now_sec = timeout->time.sec;
  519. timeout->time.sec += secs;
  520. if (timeout->time.sec < now_sec) {
  521. /*
  522. * Integer overflow - assume long enough timeout to be assumed
  523. * to be infinite, i.e., the timeout would never happen.
  524. */
  525. wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
  526. "ever happen - ignore it", secs);
  527. os_free(timeout);
  528. return 0;
  529. }
  530. timeout->time.usec += usecs;
  531. while (timeout->time.usec >= 1000000) {
  532. timeout->time.sec++;
  533. timeout->time.usec -= 1000000;
  534. }
  535. timeout->eloop_data = eloop_data;
  536. timeout->user_data = user_data;
  537. timeout->handler = handler;
  538. wpa_trace_add_ref(timeout, eloop, eloop_data);
  539. wpa_trace_add_ref(timeout, user, user_data);
  540. wpa_trace_record(timeout);
  541. /* Maintain timeouts in order of increasing time */
  542. dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
  543. if (os_reltime_before(&timeout->time, &tmp->time)) {
  544. dl_list_add(tmp->list.prev, &timeout->list);
  545. return 0;
  546. }
  547. }
  548. dl_list_add_tail(&eloop.timeout, &timeout->list);
  549. return 0;
  550. }
  551. static void eloop_remove_timeout(struct eloop_timeout *timeout)
  552. {
  553. dl_list_del(&timeout->list);
  554. wpa_trace_remove_ref(timeout, eloop, timeout->eloop_data);
  555. wpa_trace_remove_ref(timeout, user, timeout->user_data);
  556. os_free(timeout);
  557. }
  558. int eloop_cancel_timeout(eloop_timeout_handler handler,
  559. void *eloop_data, void *user_data)
  560. {
  561. struct eloop_timeout *timeout, *prev;
  562. int removed = 0;
  563. dl_list_for_each_safe(timeout, prev, &eloop.timeout,
  564. struct eloop_timeout, list) {
  565. if (timeout->handler == handler &&
  566. (timeout->eloop_data == eloop_data ||
  567. eloop_data == ELOOP_ALL_CTX) &&
  568. (timeout->user_data == user_data ||
  569. user_data == ELOOP_ALL_CTX)) {
  570. eloop_remove_timeout(timeout);
  571. removed++;
  572. }
  573. }
  574. return removed;
  575. }
  576. int eloop_cancel_timeout_one(eloop_timeout_handler handler,
  577. void *eloop_data, void *user_data,
  578. struct os_reltime *remaining)
  579. {
  580. struct eloop_timeout *timeout, *prev;
  581. int removed = 0;
  582. struct os_reltime now;
  583. os_get_reltime(&now);
  584. remaining->sec = remaining->usec = 0;
  585. dl_list_for_each_safe(timeout, prev, &eloop.timeout,
  586. struct eloop_timeout, list) {
  587. if (timeout->handler == handler &&
  588. (timeout->eloop_data == eloop_data) &&
  589. (timeout->user_data == user_data)) {
  590. removed = 1;
  591. if (os_reltime_before(&now, &timeout->time))
  592. os_reltime_sub(&timeout->time, &now, remaining);
  593. eloop_remove_timeout(timeout);
  594. break;
  595. }
  596. }
  597. return removed;
  598. }
  599. int eloop_is_timeout_registered(eloop_timeout_handler handler,
  600. void *eloop_data, void *user_data)
  601. {
  602. struct eloop_timeout *tmp;
  603. dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
  604. if (tmp->handler == handler &&
  605. tmp->eloop_data == eloop_data &&
  606. tmp->user_data == user_data)
  607. return 1;
  608. }
  609. return 0;
  610. }
  611. int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs,
  612. eloop_timeout_handler handler, void *eloop_data,
  613. void *user_data)
  614. {
  615. struct os_reltime now, requested, remaining;
  616. struct eloop_timeout *tmp;
  617. dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
  618. if (tmp->handler == handler &&
  619. tmp->eloop_data == eloop_data &&
  620. tmp->user_data == user_data) {
  621. requested.sec = req_secs;
  622. requested.usec = req_usecs;
  623. os_get_reltime(&now);
  624. os_reltime_sub(&tmp->time, &now, &remaining);
  625. if (os_reltime_before(&requested, &remaining)) {
  626. eloop_cancel_timeout(handler, eloop_data,
  627. user_data);
  628. eloop_register_timeout(requested.sec,
  629. requested.usec,
  630. handler, eloop_data,
  631. user_data);
  632. return 1;
  633. }
  634. return 0;
  635. }
  636. }
  637. return -1;
  638. }
  639. int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs,
  640. eloop_timeout_handler handler, void *eloop_data,
  641. void *user_data)
  642. {
  643. struct os_reltime now, requested, remaining;
  644. struct eloop_timeout *tmp;
  645. dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
  646. if (tmp->handler == handler &&
  647. tmp->eloop_data == eloop_data &&
  648. tmp->user_data == user_data) {
  649. requested.sec = req_secs;
  650. requested.usec = req_usecs;
  651. os_get_reltime(&now);
  652. os_reltime_sub(&tmp->time, &now, &remaining);
  653. if (os_reltime_before(&remaining, &requested)) {
  654. eloop_cancel_timeout(handler, eloop_data,
  655. user_data);
  656. eloop_register_timeout(requested.sec,
  657. requested.usec,
  658. handler, eloop_data,
  659. user_data);
  660. return 1;
  661. }
  662. return 0;
  663. }
  664. }
  665. return -1;
  666. }
  667. #ifndef CONFIG_NATIVE_WINDOWS
  668. static void eloop_handle_alarm(int sig)
  669. {
  670. wpa_printf(MSG_ERROR, "eloop: could not process SIGINT or SIGTERM in "
  671. "two seconds. Looks like there\n"
  672. "is a bug that ends up in a busy loop that "
  673. "prevents clean shutdown.\n"
  674. "Killing program forcefully.\n");
  675. exit(1);
  676. }
  677. #endif /* CONFIG_NATIVE_WINDOWS */
  678. static void eloop_handle_signal(int sig)
  679. {
  680. int i;
  681. #ifndef CONFIG_NATIVE_WINDOWS
  682. if ((sig == SIGINT || sig == SIGTERM) && !eloop.pending_terminate) {
  683. /* Use SIGALRM to break out from potential busy loops that
  684. * would not allow the program to be killed. */
  685. eloop.pending_terminate = 1;
  686. signal(SIGALRM, eloop_handle_alarm);
  687. alarm(2);
  688. }
  689. #endif /* CONFIG_NATIVE_WINDOWS */
  690. eloop.signaled++;
  691. for (i = 0; i < eloop.signal_count; i++) {
  692. if (eloop.signals[i].sig == sig) {
  693. eloop.signals[i].signaled++;
  694. break;
  695. }
  696. }
  697. }
  698. static void eloop_process_pending_signals(void)
  699. {
  700. int i;
  701. if (eloop.signaled == 0)
  702. return;
  703. eloop.signaled = 0;
  704. if (eloop.pending_terminate) {
  705. #ifndef CONFIG_NATIVE_WINDOWS
  706. alarm(0);
  707. #endif /* CONFIG_NATIVE_WINDOWS */
  708. eloop.pending_terminate = 0;
  709. }
  710. for (i = 0; i < eloop.signal_count; i++) {
  711. if (eloop.signals[i].signaled) {
  712. eloop.signals[i].signaled = 0;
  713. eloop.signals[i].handler(eloop.signals[i].sig,
  714. eloop.signals[i].user_data);
  715. }
  716. }
  717. }
  718. int eloop_register_signal(int sig, eloop_signal_handler handler,
  719. void *user_data)
  720. {
  721. struct eloop_signal *tmp;
  722. tmp = os_realloc_array(eloop.signals, eloop.signal_count + 1,
  723. sizeof(struct eloop_signal));
  724. if (tmp == NULL)
  725. return -1;
  726. tmp[eloop.signal_count].sig = sig;
  727. tmp[eloop.signal_count].user_data = user_data;
  728. tmp[eloop.signal_count].handler = handler;
  729. tmp[eloop.signal_count].signaled = 0;
  730. eloop.signal_count++;
  731. eloop.signals = tmp;
  732. signal(sig, eloop_handle_signal);
  733. return 0;
  734. }
  735. int eloop_register_signal_terminate(eloop_signal_handler handler,
  736. void *user_data)
  737. {
  738. int ret = eloop_register_signal(SIGINT, handler, user_data);
  739. if (ret == 0)
  740. ret = eloop_register_signal(SIGTERM, handler, user_data);
  741. return ret;
  742. }
  743. int eloop_register_signal_reconfig(eloop_signal_handler handler,
  744. void *user_data)
  745. {
  746. #ifdef CONFIG_NATIVE_WINDOWS
  747. return 0;
  748. #else /* CONFIG_NATIVE_WINDOWS */
  749. return eloop_register_signal(SIGHUP, handler, user_data);
  750. #endif /* CONFIG_NATIVE_WINDOWS */
  751. }
  752. void eloop_run(void)
  753. {
  754. #ifdef CONFIG_ELOOP_POLL
  755. int num_poll_fds;
  756. int timeout_ms = 0;
  757. #endif /* CONFIG_ELOOP_POLL */
  758. #ifdef CONFIG_ELOOP_SELECT
  759. fd_set *rfds, *wfds, *efds;
  760. struct timeval _tv;
  761. #endif /* CONFIG_ELOOP_SELECT */
  762. #ifdef CONFIG_ELOOP_EPOLL
  763. int timeout_ms = -1;
  764. #endif /* CONFIG_ELOOP_EPOLL */
  765. int res;
  766. struct os_reltime tv, now;
  767. #ifdef CONFIG_ELOOP_SELECT
  768. rfds = os_malloc(sizeof(*rfds));
  769. wfds = os_malloc(sizeof(*wfds));
  770. efds = os_malloc(sizeof(*efds));
  771. if (rfds == NULL || wfds == NULL || efds == NULL)
  772. goto out;
  773. #endif /* CONFIG_ELOOP_SELECT */
  774. while (!eloop.terminate &&
  775. (!dl_list_empty(&eloop.timeout) || eloop.readers.count > 0 ||
  776. eloop.writers.count > 0 || eloop.exceptions.count > 0)) {
  777. struct eloop_timeout *timeout;
  778. timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
  779. list);
  780. if (timeout) {
  781. os_get_reltime(&now);
  782. if (os_reltime_before(&now, &timeout->time))
  783. os_reltime_sub(&timeout->time, &now, &tv);
  784. else
  785. tv.sec = tv.usec = 0;
  786. #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL)
  787. timeout_ms = tv.sec * 1000 + tv.usec / 1000;
  788. #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */
  789. #ifdef CONFIG_ELOOP_SELECT
  790. _tv.tv_sec = tv.sec;
  791. _tv.tv_usec = tv.usec;
  792. #endif /* CONFIG_ELOOP_SELECT */
  793. }
  794. #ifdef CONFIG_ELOOP_POLL
  795. num_poll_fds = eloop_sock_table_set_fds(
  796. &eloop.readers, &eloop.writers, &eloop.exceptions,
  797. eloop.pollfds, eloop.pollfds_map,
  798. eloop.max_pollfd_map);
  799. res = poll(eloop.pollfds, num_poll_fds,
  800. timeout ? timeout_ms : -1);
  801. #endif /* CONFIG_ELOOP_POLL */
  802. #ifdef CONFIG_ELOOP_SELECT
  803. eloop_sock_table_set_fds(&eloop.readers, rfds);
  804. eloop_sock_table_set_fds(&eloop.writers, wfds);
  805. eloop_sock_table_set_fds(&eloop.exceptions, efds);
  806. res = select(eloop.max_sock + 1, rfds, wfds, efds,
  807. timeout ? &_tv : NULL);
  808. #endif /* CONFIG_ELOOP_SELECT */
  809. #ifdef CONFIG_ELOOP_EPOLL
  810. if (eloop.count == 0) {
  811. res = 0;
  812. } else {
  813. res = epoll_wait(eloop.epollfd, eloop.epoll_events,
  814. eloop.count, timeout_ms);
  815. }
  816. #endif /* CONFIG_ELOOP_EPOLL */
  817. if (res < 0 && errno != EINTR && errno != 0) {
  818. wpa_printf(MSG_ERROR, "eloop: %s: %s",
  819. #ifdef CONFIG_ELOOP_POLL
  820. "poll"
  821. #endif /* CONFIG_ELOOP_POLL */
  822. #ifdef CONFIG_ELOOP_SELECT
  823. "select"
  824. #endif /* CONFIG_ELOOP_SELECT */
  825. #ifdef CONFIG_ELOOP_EPOLL
  826. "epoll"
  827. #endif /* CONFIG_ELOOP_EPOLL */
  828. , strerror(errno));
  829. goto out;
  830. }
  831. eloop_process_pending_signals();
  832. /* check if some registered timeouts have occurred */
  833. timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
  834. list);
  835. if (timeout) {
  836. os_get_reltime(&now);
  837. if (!os_reltime_before(&now, &timeout->time)) {
  838. void *eloop_data = timeout->eloop_data;
  839. void *user_data = timeout->user_data;
  840. eloop_timeout_handler handler =
  841. timeout->handler;
  842. eloop_remove_timeout(timeout);
  843. handler(eloop_data, user_data);
  844. }
  845. }
  846. if (res <= 0)
  847. continue;
  848. #ifdef CONFIG_ELOOP_POLL
  849. eloop_sock_table_dispatch(&eloop.readers, &eloop.writers,
  850. &eloop.exceptions, eloop.pollfds_map,
  851. eloop.max_pollfd_map);
  852. #endif /* CONFIG_ELOOP_POLL */
  853. #ifdef CONFIG_ELOOP_SELECT
  854. eloop_sock_table_dispatch(&eloop.readers, rfds);
  855. eloop_sock_table_dispatch(&eloop.writers, wfds);
  856. eloop_sock_table_dispatch(&eloop.exceptions, efds);
  857. #endif /* CONFIG_ELOOP_SELECT */
  858. #ifdef CONFIG_ELOOP_EPOLL
  859. eloop_sock_table_dispatch(eloop.epoll_events, res);
  860. #endif /* CONFIG_ELOOP_EPOLL */
  861. }
  862. eloop.terminate = 0;
  863. out:
  864. #ifdef CONFIG_ELOOP_SELECT
  865. os_free(rfds);
  866. os_free(wfds);
  867. os_free(efds);
  868. #endif /* CONFIG_ELOOP_SELECT */
  869. return;
  870. }
  871. void eloop_terminate(void)
  872. {
  873. eloop.terminate = 1;
  874. }
  875. void eloop_destroy(void)
  876. {
  877. struct eloop_timeout *timeout, *prev;
  878. struct os_reltime now;
  879. os_get_reltime(&now);
  880. dl_list_for_each_safe(timeout, prev, &eloop.timeout,
  881. struct eloop_timeout, list) {
  882. int sec, usec;
  883. sec = timeout->time.sec - now.sec;
  884. usec = timeout->time.usec - now.usec;
  885. if (timeout->time.usec < now.usec) {
  886. sec--;
  887. usec += 1000000;
  888. }
  889. wpa_printf(MSG_INFO, "ELOOP: remaining timeout: %d.%06d "
  890. "eloop_data=%p user_data=%p handler=%p",
  891. sec, usec, timeout->eloop_data, timeout->user_data,
  892. timeout->handler);
  893. wpa_trace_dump_funcname("eloop unregistered timeout handler",
  894. timeout->handler);
  895. wpa_trace_dump("eloop timeout", timeout);
  896. eloop_remove_timeout(timeout);
  897. }
  898. eloop_sock_table_destroy(&eloop.readers);
  899. eloop_sock_table_destroy(&eloop.writers);
  900. eloop_sock_table_destroy(&eloop.exceptions);
  901. os_free(eloop.signals);
  902. #ifdef CONFIG_ELOOP_POLL
  903. os_free(eloop.pollfds);
  904. os_free(eloop.pollfds_map);
  905. #endif /* CONFIG_ELOOP_POLL */
  906. #ifdef CONFIG_ELOOP_EPOLL
  907. os_free(eloop.epoll_table);
  908. os_free(eloop.epoll_events);
  909. close(eloop.epollfd);
  910. #endif /* CONFIG_ELOOP_EPOLL */
  911. }
  912. int eloop_terminated(void)
  913. {
  914. return eloop.terminate;
  915. }
  916. void eloop_wait_for_read_sock(int sock)
  917. {
  918. #ifdef CONFIG_ELOOP_POLL
  919. struct pollfd pfd;
  920. if (sock < 0)
  921. return;
  922. os_memset(&pfd, 0, sizeof(pfd));
  923. pfd.fd = sock;
  924. pfd.events = POLLIN;
  925. poll(&pfd, 1, -1);
  926. #endif /* CONFIG_ELOOP_POLL */
  927. #if defined(CONFIG_ELOOP_SELECT) || defined(CONFIG_ELOOP_EPOLL)
  928. /*
  929. * We can use epoll() here. But epoll() requres 4 system calls.
  930. * epoll_create1(), epoll_ctl() for ADD, epoll_wait, and close() for
  931. * epoll fd. So select() is better for performance here.
  932. */
  933. fd_set rfds;
  934. if (sock < 0)
  935. return;
  936. FD_ZERO(&rfds);
  937. FD_SET(sock, &rfds);
  938. select(sock + 1, &rfds, NULL, NULL, NULL);
  939. #endif /* defined(CONFIG_ELOOP_SELECT) || defined(CONFIG_ELOOP_EPOLL) */
  940. }
  941. #ifdef CONFIG_ELOOP_SELECT
  942. #undef CONFIG_ELOOP_SELECT
  943. #endif /* CONFIG_ELOOP_SELECT */