io.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation; either version 2 of the License, or
  5. * (at your option) any later version.
  6. * Please read the file COPYING, README and AUTHORS for more information.
  7. *
  8. * I/O abstraction interface.
  9. * Copyright (c) 2005 Florian Westphal (westphal@foo.fh-furtwangen.de)
  10. *
  11. */
  12. #include "portab.h"
  13. static char UNUSED id[] = "$Id: io.c,v 1.16.2.1 2007/04/03 22:08:52 fw Exp $";
  14. #include <assert.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <sys/time.h>
  18. #include <sys/types.h>
  19. #include <unistd.h>
  20. #include <fcntl.h>
  21. #include "array.h"
  22. #include "io.h"
  23. #include "log.h"
  24. /* Enables extra debug messages in event add/delete/callback code. */
  25. /* #define DEBUG_IO */
  26. typedef struct {
  27. void (*callback)(int, short);
  28. short what;
  29. } io_event;
  30. #define INIT_IOEVENT { NULL, -1, 0, NULL }
  31. #define IO_ERROR 4
  32. #ifdef HAVE_EPOLL_CREATE
  33. # define IO_USE_EPOLL 1
  34. # ifdef HAVE_SELECT
  35. # define IO_USE_SELECT 1
  36. # endif
  37. #else
  38. # ifdef HAVE_KQUEUE
  39. # define IO_USE_KQUEUE 1
  40. # else
  41. # ifdef HAVE_SYS_DEVPOLL_H
  42. # define IO_USE_DEVPOLL 1
  43. # else
  44. # ifdef HAVE_POLL
  45. # define IO_USE_POLL 1
  46. # else
  47. # ifdef HAVE_SELECT
  48. # define IO_USE_SELECT 1
  49. # else
  50. # error "no IO API available!?"
  51. # endif /* HAVE_SELECT */
  52. # endif /* HAVE_POLL */
  53. # endif /* HAVE_SYS_DEVPOLL_H */
  54. # endif /* HAVE_KQUEUE */
  55. #endif /* HAVE_EPOLL_CREATE */
  56. static bool library_initialized = false;
  57. #ifdef IO_USE_EPOLL
  58. #include <sys/epoll.h>
  59. static int io_masterfd = -1;
  60. static bool io_event_change_epoll(int fd, short what, const int action);
  61. static int io_dispatch_epoll(struct timeval *tv);
  62. #endif
  63. #ifdef IO_USE_KQUEUE
  64. #include <sys/types.h>
  65. #include <sys/event.h>
  66. static array io_evcache;
  67. static int io_masterfd;
  68. static int io_dispatch_kqueue(struct timeval *tv);
  69. static bool io_event_change_kqueue(int, short, const int action);
  70. #endif
  71. #ifdef IO_USE_POLL
  72. #include <poll.h>
  73. static array pollfds;
  74. static int poll_maxfd;
  75. static bool io_event_change_poll(int fd, short what);
  76. #endif
  77. #ifdef IO_USE_DEVPOLL
  78. #include <sys/devpoll.h>
  79. static int io_masterfd;
  80. static bool io_event_change_devpoll(int fd, short what);
  81. #endif
  82. #ifdef IO_USE_SELECT
  83. #include "defines.h" /* for conn.h */
  84. #include "conn.h" /* for CONN_IDX (needed by resolve.h) */
  85. #include "resolve.h" /* for RES_STAT (needed by conf.h) */
  86. #include "conf.h" /* for Conf_MaxConnections */
  87. static fd_set readers;
  88. static fd_set writers;
  89. static int select_maxfd; /* the select() interface sucks badly */
  90. static int io_dispatch_select(struct timeval *tv);
  91. #ifndef IO_USE_EPOLL
  92. #define io_masterfd -1
  93. #endif
  94. #endif /* IO_USE_SELECT */
  95. static array io_events;
  96. static void io_docallback PARAMS((int fd, short what));
  97. static io_event *
  98. io_event_get(int fd)
  99. {
  100. io_event *i;
  101. assert(fd >= 0);
  102. i = (io_event *) array_get(&io_events, sizeof(io_event), (size_t) fd);
  103. assert(i != NULL);
  104. return i;
  105. }
  106. #ifdef IO_USE_DEVPOLL
  107. static void
  108. io_library_init_devpoll(unsigned int eventsize)
  109. {
  110. io_masterfd = open("/dev/poll", O_RDWR);
  111. if (io_masterfd >= 0)
  112. library_initialized = true;
  113. Log(LOG_INFO, "IO subsystem: /dev/poll (initial maxfd %u, masterfd %d).",
  114. eventsize, io_masterfd);
  115. }
  116. #endif
  117. #ifdef IO_USE_POLL
  118. static void
  119. io_library_init_poll(unsigned int eventsize)
  120. {
  121. struct pollfd *p;
  122. array_init(&pollfds);
  123. poll_maxfd = 0;
  124. Log(LOG_INFO, "IO subsystem: poll (initial maxfd %u).",
  125. eventsize);
  126. p = array_alloc(&pollfds, sizeof(struct pollfd), eventsize);
  127. if (p) {
  128. unsigned i;
  129. p = array_start(&pollfds);
  130. for (i = 0; i < eventsize; i++)
  131. p[i].fd = -1;
  132. library_initialized = true;
  133. }
  134. }
  135. #endif
  136. #ifdef IO_USE_SELECT
  137. static void
  138. io_library_init_select(unsigned int eventsize)
  139. {
  140. Log(LOG_INFO, "IO subsystem: select (initial maxfd %u).",
  141. eventsize);
  142. FD_ZERO(&readers);
  143. FD_ZERO(&writers);
  144. #ifdef FD_SETSIZE
  145. if (Conf_MaxConnections >= (int)FD_SETSIZE) {
  146. Log(LOG_WARNING,
  147. "MaxConnections (%d) exceeds limit (%u), changed MaxConnections to %u.",
  148. Conf_MaxConnections, FD_SETSIZE, FD_SETSIZE - 1);
  149. Conf_MaxConnections = FD_SETSIZE - 1;
  150. }
  151. #endif /* FD_SETSIZE */
  152. library_initialized = true;
  153. }
  154. #endif /* SELECT */
  155. #ifdef IO_USE_EPOLL
  156. static void
  157. io_library_init_epoll(unsigned int eventsize)
  158. {
  159. int ecreate_hint = (int)eventsize;
  160. if (ecreate_hint <= 0)
  161. ecreate_hint = 128;
  162. io_masterfd = epoll_create(ecreate_hint);
  163. if (io_masterfd >= 0) {
  164. library_initialized = true;
  165. Log(LOG_INFO,
  166. "IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).",
  167. ecreate_hint, eventsize, io_masterfd);
  168. }
  169. }
  170. #endif
  171. #ifdef IO_USE_KQUEUE
  172. static void
  173. io_library_init_kqueue(unsigned int eventsize)
  174. {
  175. io_masterfd = kqueue();
  176. Log(LOG_INFO,
  177. "IO subsystem: kqueue (initial maxfd %u, masterfd %d)",
  178. eventsize, io_masterfd);
  179. if (io_masterfd >= 0)
  180. library_initialized = true;
  181. }
  182. #endif
  183. bool
  184. io_library_init(unsigned int eventsize)
  185. {
  186. if (library_initialized)
  187. return true;
  188. #ifdef IO_USE_SELECT
  189. #ifndef FD_SETSIZE
  190. Log(LOG_WARNING,
  191. "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ...");
  192. #else
  193. if (eventsize >= FD_SETSIZE)
  194. eventsize = FD_SETSIZE - 1;
  195. #endif /* FD_SETSIZE */
  196. #endif /* IO_USE_SELECT */
  197. if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize))
  198. eventsize = 0;
  199. #ifdef IO_USE_EPOLL
  200. io_library_init_epoll(eventsize);
  201. #ifdef IO_USE_SELECT
  202. if (io_masterfd < 0)
  203. Log(LOG_INFO, "Can't initialize epoll() IO interface, falling back to select() ...");
  204. #endif
  205. #endif
  206. #ifdef IO_USE_KQUEUE
  207. io_library_init_kqueue(eventsize);
  208. #endif
  209. #ifdef IO_USE_DEVPOLL
  210. io_library_init_devpoll(eventsize);
  211. #endif
  212. #ifdef IO_USE_POLL
  213. io_library_init_poll(eventsize);
  214. #endif
  215. #ifdef IO_USE_SELECT
  216. if (! library_initialized)
  217. io_library_init_select(eventsize);
  218. #endif
  219. return library_initialized;
  220. }
  221. void
  222. io_library_shutdown(void)
  223. {
  224. #ifdef IO_USE_SELECT
  225. FD_ZERO(&readers);
  226. FD_ZERO(&writers);
  227. #endif
  228. #ifdef IO_USE_EPOLL
  229. if (io_masterfd >= 0)
  230. close(io_masterfd);
  231. io_masterfd = -1;
  232. #endif
  233. #ifdef IO_USE_KQUEUE
  234. close(io_masterfd);
  235. io_masterfd = -1;
  236. array_free(&io_evcache);
  237. #endif
  238. library_initialized = false;
  239. }
  240. bool
  241. io_event_setcb(int fd, void (*cbfunc) (int, short))
  242. {
  243. io_event *i = io_event_get(fd);
  244. if (!i)
  245. return false;
  246. i->callback = cbfunc;
  247. return true;
  248. }
  249. bool
  250. io_event_create(int fd, short what, void (*cbfunc) (int, short))
  251. {
  252. bool ret;
  253. io_event *i;
  254. assert(fd >= 0);
  255. #if defined(IO_USE_SELECT) && defined(FD_SETSIZE)
  256. if (fd >= FD_SETSIZE) {
  257. Log(LOG_ERR,
  258. "fd %d exceeds FD_SETSIZE (%u) (select can't handle more file descriptors)",
  259. fd, FD_SETSIZE);
  260. return false;
  261. }
  262. #endif
  263. i = (io_event *) array_alloc(&io_events, sizeof(io_event), (size_t) fd);
  264. if (!i) {
  265. Log(LOG_WARNING,
  266. "array_alloc failed: could not allocate space for %d io_event structures",
  267. fd);
  268. return false;
  269. }
  270. i->callback = cbfunc;
  271. i->what = 0;
  272. #ifdef IO_USE_DEVPOLL
  273. ret = io_event_change_devpoll(fd, what);
  274. #endif
  275. #ifdef IO_USE_POLL
  276. ret = io_event_change_poll(fd, what);
  277. #endif
  278. #ifdef IO_USE_EPOLL
  279. ret = io_event_change_epoll(fd, what, EPOLL_CTL_ADD);
  280. #endif
  281. #ifdef IO_USE_KQUEUE
  282. ret = io_event_change_kqueue(fd, what, EV_ADD|EV_ENABLE);
  283. #endif
  284. #ifdef IO_USE_SELECT
  285. if (io_masterfd < 0)
  286. ret = io_event_add(fd, what);
  287. #endif
  288. if (ret) i->what = what;
  289. return ret;
  290. }
  291. #ifdef IO_USE_DEVPOLL
  292. static bool
  293. io_event_change_devpoll(int fd, short what)
  294. {
  295. struct pollfd p;
  296. p.events = 0;
  297. if (what & IO_WANTREAD)
  298. p.events = POLLIN | POLLPRI;
  299. if (what & IO_WANTWRITE)
  300. p.events |= POLLOUT;
  301. p.fd = fd;
  302. return write(io_masterfd, &p, sizeof p) == (ssize_t)sizeof p;
  303. }
  304. #endif
  305. #ifdef IO_USE_POLL
  306. static bool
  307. io_event_change_poll(int fd, short what)
  308. {
  309. struct pollfd *p;
  310. short events = 0;
  311. if (what & IO_WANTREAD)
  312. events = POLLIN | POLLPRI;
  313. if (what & IO_WANTWRITE)
  314. events |= POLLOUT;
  315. p = array_alloc(&pollfds, sizeof *p, fd);
  316. if (p) {
  317. p->events = events;
  318. p->fd = fd;
  319. if (fd > poll_maxfd)
  320. poll_maxfd = fd;
  321. }
  322. return p != NULL;
  323. }
  324. #endif
  325. #ifdef IO_USE_EPOLL
  326. static bool
  327. io_event_change_epoll(int fd, short what, const int action)
  328. {
  329. struct epoll_event ev = { 0, {0} };
  330. ev.data.fd = fd;
  331. if (what & IO_WANTREAD)
  332. ev.events = EPOLLIN | EPOLLPRI;
  333. if (what & IO_WANTWRITE)
  334. ev.events |= EPOLLOUT;
  335. return epoll_ctl(io_masterfd, action, fd, &ev) == 0;
  336. }
  337. #endif
  338. #ifdef IO_USE_KQUEUE
  339. static bool
  340. io_event_kqueue_commit_cache(void)
  341. {
  342. struct kevent *events;
  343. bool ret;
  344. int len = (int) array_length(&io_evcache, sizeof (struct kevent));
  345. if (!len) /* nothing to do */
  346. return true;
  347. assert(len>0);
  348. if (len < 0) {
  349. array_free(&io_evcache);
  350. return false;
  351. }
  352. events = array_start(&io_evcache);
  353. assert(events != NULL);
  354. ret = kevent(io_masterfd, events, len, NULL, 0, NULL) == 0;
  355. if (ret)
  356. array_trunc(&io_evcache);
  357. return ret;
  358. }
  359. static bool
  360. io_event_change_kqueue(int fd, short what, const int action)
  361. {
  362. struct kevent kev;
  363. bool ret = true;
  364. if (what & IO_WANTREAD) {
  365. EV_SET(&kev, fd, EVFILT_READ, action, 0, 0, 0);
  366. ret = array_catb(&io_evcache, (char*) &kev, sizeof (kev));
  367. if (!ret)
  368. ret = kevent(io_masterfd, &kev,1, NULL, 0, NULL) == 0;
  369. }
  370. if (ret && (what & IO_WANTWRITE)) {
  371. EV_SET(&kev, fd, EVFILT_WRITE, action, 0, 0, 0);
  372. ret = array_catb(&io_evcache, (char*) &kev, sizeof (kev));
  373. if (!ret)
  374. ret = kevent(io_masterfd, &kev, 1, NULL, 0, NULL) == 0;
  375. }
  376. if (array_length(&io_evcache, sizeof kev) >= 100)
  377. io_event_kqueue_commit_cache();
  378. return ret;
  379. }
  380. #endif
  381. bool
  382. io_event_add(int fd, short what)
  383. {
  384. io_event *i = io_event_get(fd);
  385. if (!i) return false;
  386. if ((i->what & what) == what) /* event type is already registered */
  387. return true;
  388. #ifdef DEBUG_IO
  389. Log(LOG_DEBUG, "io_event_add(): fd %d, what %d.", fd, what);
  390. #endif
  391. i->what |= what;
  392. #ifdef IO_USE_EPOLL
  393. if (io_masterfd >= 0)
  394. return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
  395. #endif
  396. #ifdef IO_USE_KQUEUE
  397. return io_event_change_kqueue(fd, what, EV_ADD | EV_ENABLE);
  398. #endif
  399. #ifdef IO_USE_DEVPOLL
  400. return io_event_change_devpoll(fd, i->what);
  401. #endif
  402. #ifdef IO_USE_POLL
  403. return io_event_change_poll(fd, i->what);
  404. #endif
  405. #ifdef IO_USE_SELECT
  406. if (fd > select_maxfd)
  407. select_maxfd = fd;
  408. if (what & IO_WANTREAD)
  409. FD_SET(fd, &readers);
  410. if (what & IO_WANTWRITE)
  411. FD_SET(fd, &writers);
  412. return true;
  413. #endif
  414. }
  415. bool
  416. io_setnonblock(int fd)
  417. {
  418. int flags = fcntl(fd, F_GETFL);
  419. if (flags == -1)
  420. return false;
  421. #ifndef O_NONBLOCK
  422. #define O_NONBLOCK O_NDELAY
  423. #endif
  424. flags |= O_NONBLOCK;
  425. return fcntl(fd, F_SETFL, flags) == 0;
  426. }
  427. #ifdef IO_USE_DEVPOLL
  428. static void
  429. io_close_devpoll(int fd)
  430. {
  431. struct pollfd p;
  432. p.events = POLLREMOVE;
  433. p.fd = fd;
  434. write(io_masterfd, &p, sizeof p);
  435. }
  436. #else
  437. static inline void io_close_devpoll(int UNUSED x) { /* NOTHING */ }
  438. #endif
  439. #ifdef IO_USE_POLL
  440. static void
  441. io_close_poll(int fd)
  442. {
  443. struct pollfd *p;
  444. p = array_get(&pollfds, sizeof *p, fd);
  445. if (!p) return;
  446. p->fd = -1;
  447. if (fd == poll_maxfd) {
  448. while (poll_maxfd > 0) {
  449. --poll_maxfd;
  450. p = array_get(&pollfds, sizeof *p, poll_maxfd);
  451. if (p && p->fd >= 0)
  452. break;
  453. }
  454. }
  455. }
  456. #else
  457. static inline void io_close_poll(int UNUSED x) { /* NOTHING */ }
  458. #endif
  459. #ifdef IO_USE_SELECT
  460. static void
  461. io_close_select(int fd)
  462. {
  463. io_event *i;
  464. if (io_masterfd >= 0) /* Are we using epoll()? */
  465. return;
  466. FD_CLR(fd, &writers);
  467. FD_CLR(fd, &readers);
  468. i = io_event_get(fd);
  469. if (!i) return;
  470. if (fd == select_maxfd) {
  471. while (select_maxfd>0) {
  472. --select_maxfd; /* find largest fd */
  473. i = io_event_get(select_maxfd);
  474. if (i && i->callback) break;
  475. }
  476. }
  477. }
  478. #else
  479. static inline void io_close_select(int UNUSED x) { /* NOTHING */ }
  480. #endif
  481. bool
  482. io_close(int fd)
  483. {
  484. io_event *i;
  485. i = io_event_get(fd);
  486. #ifdef IO_USE_KQUEUE
  487. if (array_length(&io_evcache, sizeof (struct kevent))) /* pending data in cache? */
  488. io_event_kqueue_commit_cache();
  489. /* both kqueue and epoll remove fd from all sets automatically on the last close
  490. * of the descriptor. since we don't know if this is the last close we'll have
  491. * to remove the set explicitly. */
  492. if (i) {
  493. io_event_change_kqueue(fd, i->what, EV_DELETE);
  494. io_event_kqueue_commit_cache();
  495. }
  496. #endif
  497. io_close_devpoll(fd);
  498. io_close_poll(fd);
  499. io_close_select(fd);
  500. #ifdef IO_USE_EPOLL
  501. io_event_change_epoll(fd, 0, EPOLL_CTL_DEL);
  502. #endif
  503. if (i) {
  504. i->callback = NULL;
  505. i->what = 0;
  506. }
  507. return close(fd) == 0;
  508. }
  509. bool
  510. io_event_del(int fd, short what)
  511. {
  512. io_event *i = io_event_get(fd);
  513. #ifdef DEBUG_IO
  514. Log(LOG_DEBUG, "io_event_del(): trying to delete eventtype %d on fd %d", what, fd);
  515. #endif
  516. if (!i) return false;
  517. i->what &= ~what;
  518. #ifdef IO_USE_DEVPOLL
  519. return io_event_change_devpoll(fd, i->what);
  520. #endif
  521. #ifdef IO_USE_POLL
  522. return io_event_change_poll(fd, i->what);
  523. #endif
  524. #ifdef IO_USE_EPOLL
  525. if (io_masterfd >= 0)
  526. return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
  527. #endif
  528. #ifdef IO_USE_KQUEUE
  529. return io_event_change_kqueue(fd, what, EV_DISABLE);
  530. #endif
  531. #ifdef IO_USE_SELECT
  532. if (what & IO_WANTWRITE)
  533. FD_CLR(fd, &writers);
  534. if (what & IO_WANTREAD)
  535. FD_CLR(fd, &readers);
  536. return true;
  537. #endif
  538. }
  539. #ifdef IO_USE_SELECT
  540. static int
  541. io_dispatch_select(struct timeval *tv)
  542. {
  543. fd_set readers_tmp = readers;
  544. fd_set writers_tmp = writers;
  545. short what;
  546. int ret, i;
  547. int fds_ready;
  548. ret = select(select_maxfd + 1, &readers_tmp, &writers_tmp, NULL, tv);
  549. if (ret <= 0)
  550. return ret;
  551. fds_ready = ret;
  552. for (i = 0; i <= select_maxfd; i++) {
  553. what = 0;
  554. if (FD_ISSET(i, &readers_tmp)) {
  555. what = IO_WANTREAD;
  556. fds_ready--;
  557. }
  558. if (FD_ISSET(i, &writers_tmp)) {
  559. what |= IO_WANTWRITE;
  560. fds_ready--;
  561. }
  562. if (what)
  563. io_docallback(i, what);
  564. if (fds_ready <= 0)
  565. break;
  566. }
  567. return ret;
  568. }
  569. #endif
  570. #ifdef IO_USE_DEVPOLL
  571. static int
  572. io_dispatch_devpoll(struct timeval *tv)
  573. {
  574. struct dvpoll dvp;
  575. time_t sec = tv->tv_sec * 1000;
  576. int i, total, ret, timeout = tv->tv_usec + sec;
  577. short what;
  578. struct pollfd p[100];
  579. if (timeout < 0)
  580. timeout = 1000;
  581. total = 0;
  582. do {
  583. dvp.dp_timeout = timeout;
  584. dvp.dp_nfds = 100;
  585. dvp.dp_fds = p;
  586. ret = ioctl(io_masterfd, DP_POLL, &dvp);
  587. total += ret;
  588. if (ret <= 0)
  589. return total;
  590. for (i=0; i < ret ; i++) {
  591. what = 0;
  592. if (p[i].revents & (POLLIN|POLLPRI))
  593. what = IO_WANTREAD;
  594. if (p[i].revents & POLLOUT)
  595. what |= IO_WANTWRITE;
  596. if (p[i].revents && !what) {
  597. /* other flag is set, probably POLLERR */
  598. what = IO_ERROR;
  599. }
  600. io_docallback(p[i].fd, what);
  601. }
  602. } while (ret == 100);
  603. return total;
  604. }
  605. #endif
  606. #ifdef IO_USE_POLL
  607. static int
  608. io_dispatch_poll(struct timeval *tv)
  609. {
  610. time_t sec = tv->tv_sec * 1000;
  611. int i, ret, timeout = tv->tv_usec + sec;
  612. int fds_ready;
  613. short what;
  614. struct pollfd *p = array_start(&pollfds);
  615. if (timeout < 0)
  616. timeout = 1000;
  617. ret = poll(p, poll_maxfd + 1, timeout);
  618. if (ret <= 0)
  619. return ret;
  620. fds_ready = ret;
  621. for (i=0; i <= poll_maxfd; i++) {
  622. what = 0;
  623. if (p[i].revents & (POLLIN|POLLPRI))
  624. what = IO_WANTREAD;
  625. if (p[i].revents & POLLOUT)
  626. what |= IO_WANTWRITE;
  627. if (p[i].revents && !what) {
  628. /* other flag is set, probably POLLERR */
  629. what = IO_ERROR;
  630. }
  631. if (what) {
  632. fds_ready--;
  633. io_docallback(i, what);
  634. }
  635. if (fds_ready <= 0)
  636. break;
  637. }
  638. return ret;
  639. }
  640. #endif
  641. #ifdef IO_USE_EPOLL
  642. static int
  643. io_dispatch_epoll(struct timeval *tv)
  644. {
  645. time_t sec = tv->tv_sec * 1000;
  646. int i, total = 0, ret, timeout = tv->tv_usec + sec;
  647. struct epoll_event epoll_ev[100];
  648. short type;
  649. if (timeout < 0)
  650. timeout = 1000;
  651. do {
  652. ret = epoll_wait(io_masterfd, epoll_ev, 100, timeout);
  653. total += ret;
  654. if (ret <= 0)
  655. return total;
  656. for (i = 0; i < ret; i++) {
  657. type = 0;
  658. if (epoll_ev[i].events & (EPOLLERR | EPOLLHUP))
  659. type = IO_ERROR;
  660. if (epoll_ev[i].events & (EPOLLIN | EPOLLPRI))
  661. type |= IO_WANTREAD;
  662. if (epoll_ev[i].events & EPOLLOUT)
  663. type |= IO_WANTWRITE;
  664. io_docallback(epoll_ev[i].data.fd, type);
  665. }
  666. timeout = 0;
  667. } while (ret == 100);
  668. return total;
  669. }
  670. #endif
  671. #ifdef IO_USE_KQUEUE
  672. static int
  673. io_dispatch_kqueue(struct timeval *tv)
  674. {
  675. int i, total = 0, ret;
  676. struct kevent kev[100];
  677. struct kevent *newevents;
  678. struct timespec ts;
  679. int newevents_len;
  680. ts.tv_sec = tv->tv_sec;
  681. ts.tv_nsec = tv->tv_usec * 1000;
  682. do {
  683. newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
  684. newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
  685. assert(newevents_len >= 0);
  686. if (newevents_len < 0)
  687. newevents_len = 0;
  688. #ifdef DEBUG
  689. if (newevents_len)
  690. assert(newevents != NULL);
  691. #endif
  692. ret = kevent(io_masterfd, newevents, newevents_len, kev,
  693. 100, &ts);
  694. if ((newevents_len>0) && ret != -1)
  695. array_trunc(&io_evcache);
  696. total += ret;
  697. if (ret <= 0)
  698. return total;
  699. for (i = 0; i < ret; i++) {
  700. if (kev[i].flags & EV_EOF) {
  701. #ifdef DEBUG
  702. LogDebug("kev.flag has EV_EOF set, setting IO_ERROR",
  703. kev[i].filter, kev[i].ident);
  704. #endif
  705. io_docallback((int)kev[i].ident, IO_ERROR);
  706. continue;
  707. }
  708. switch (kev[i].filter) {
  709. case EVFILT_READ:
  710. io_docallback((int)kev[i].ident, IO_WANTREAD);
  711. break;
  712. case EVFILT_WRITE:
  713. io_docallback((int)kev[i].ident, IO_WANTWRITE);
  714. break;
  715. default:
  716. #ifdef DEBUG
  717. LogDebug("Unknown kev.filter number %d for fd %d",
  718. kev[i].filter, kev[i].ident); /* Fall through */
  719. #endif
  720. case EV_ERROR:
  721. io_docallback((int)kev[i].ident, IO_ERROR);
  722. break;
  723. }
  724. }
  725. ts.tv_sec = 0;
  726. ts.tv_nsec = 0;
  727. } while (ret == 100);
  728. return total;
  729. }
  730. #endif
  731. int
  732. io_dispatch(struct timeval *tv)
  733. {
  734. #ifdef IO_USE_EPOLL
  735. if (io_masterfd >= 0)
  736. return io_dispatch_epoll(tv);
  737. #endif
  738. #ifdef IO_USE_SELECT
  739. return io_dispatch_select(tv);
  740. #endif
  741. #ifdef IO_USE_KQUEUE
  742. return io_dispatch_kqueue(tv);
  743. #endif
  744. #ifdef IO_USE_DEVPOLL
  745. return io_dispatch_devpoll(tv);
  746. #endif
  747. #ifdef IO_USE_POLL
  748. return io_dispatch_poll(tv);
  749. #endif
  750. }
  751. /* call the callback function inside the struct matching fd */
  752. static void
  753. io_docallback(int fd, short what)
  754. {
  755. io_event *i;
  756. #ifdef DEBUG_IO
  757. Log(LOG_DEBUG, "doing callback for fd %d, what %d", fd, what);
  758. #endif
  759. i = io_event_get(fd);
  760. if (i->callback) { /* callback might be NULL if a previous callback function
  761. called io_close on this fd */
  762. i->callback(fd, (what & IO_ERROR) ? i->what : what);
  763. }
  764. /* if error indicator is set, we return the event(s) that were registered */
  765. }