event.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. /*
  2. Copyright (c) 2003-2006 by Juliusz Chroboczek
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. #include "polipo.h"
  20. #ifdef HAVE_FORK
  21. static volatile sig_atomic_t exitFlag = 0;
  22. #else
  23. static int exitFlag = 0;
  24. #endif
  25. static int in_signalCondition = 0;
  26. static TimeEventHandlerPtr timeEventQueue;
  27. static TimeEventHandlerPtr timeEventQueueLast;
  28. struct timeval current_time;
  29. struct timeval null_time = {0,0};
  30. static int fdEventSize = 0;
  31. static int fdEventNum = 0;
  32. static struct pollfd *poll_fds = NULL;
  33. static FdEventHandlerPtr *fdEvents = NULL, *fdEventsLast = NULL;
  34. int diskIsClean = 1;
  35. static int fds_invalid = 0;
  36. static inline int
  37. timeval_cmp(struct timeval *t1, struct timeval *t2)
  38. {
  39. if(t1->tv_sec < t2->tv_sec)
  40. return -1;
  41. else if(t1->tv_sec > t2->tv_sec)
  42. return +1;
  43. else if(t1->tv_usec < t2->tv_usec)
  44. return -1;
  45. else if(t1->tv_usec > t2->tv_usec)
  46. return +1;
  47. else
  48. return 0;
  49. }
  50. static inline void
  51. timeval_minus(struct timeval *d,
  52. const struct timeval *s1, const struct timeval *s2)
  53. {
  54. if(s1->tv_usec >= s2->tv_usec) {
  55. d->tv_usec = s1->tv_usec - s2->tv_usec;
  56. d->tv_sec = s1->tv_sec - s2->tv_sec;
  57. } else {
  58. d->tv_usec = s1->tv_usec + 1000000 - s2->tv_usec;
  59. d->tv_sec = s1->tv_sec - s2->tv_sec - 1;
  60. }
  61. }
  62. int
  63. timeval_minus_usec(const struct timeval *s1, const struct timeval *s2)
  64. {
  65. return (s1->tv_sec - s2->tv_sec) * 1000000 + s1->tv_usec - s2->tv_usec;
  66. }
  67. #ifdef HAVE_FORK
  68. static void
  69. sigexit(int signo)
  70. {
  71. if(signo == SIGUSR1)
  72. exitFlag = 1;
  73. else if(signo == SIGUSR2)
  74. exitFlag = 2;
  75. else
  76. exitFlag = 3;
  77. }
  78. #endif
  79. void
  80. initEvents()
  81. {
  82. #ifdef HAVE_FORK
  83. struct sigaction sa;
  84. sigset_t ss;
  85. sigemptyset(&ss);
  86. sa.sa_handler = SIG_IGN;
  87. sa.sa_mask = ss;
  88. sa.sa_flags = 0;
  89. sigaction(SIGPIPE, &sa, NULL);
  90. sigemptyset(&ss);
  91. sa.sa_handler = sigexit;
  92. sa.sa_mask = ss;
  93. sa.sa_flags = 0;
  94. sigaction(SIGTERM, &sa, NULL);
  95. sigemptyset(&ss);
  96. sa.sa_handler = sigexit;
  97. sa.sa_mask = ss;
  98. sa.sa_flags = 0;
  99. sigaction(SIGHUP, &sa, NULL);
  100. sigemptyset(&ss);
  101. sa.sa_handler = sigexit;
  102. sa.sa_mask = ss;
  103. sa.sa_flags = 0;
  104. sigaction(SIGINT, &sa, NULL);
  105. sigemptyset(&ss);
  106. sa.sa_handler = sigexit;
  107. sa.sa_mask = ss;
  108. sa.sa_flags = 0;
  109. sigaction(SIGUSR1, &sa, NULL);
  110. sigemptyset(&ss);
  111. sa.sa_handler = sigexit;
  112. sa.sa_mask = ss;
  113. sa.sa_flags = 0;
  114. sigaction(SIGUSR2, &sa, NULL);
  115. #endif
  116. timeEventQueue = NULL;
  117. timeEventQueueLast = NULL;
  118. fdEventSize = 0;
  119. fdEventNum = 0;
  120. poll_fds = NULL;
  121. fdEvents = NULL;
  122. fdEventsLast = NULL;
  123. }
  124. void
  125. uninitEvents(void)
  126. {
  127. #ifdef HAVE_FORK
  128. struct sigaction sa;
  129. sigset_t ss;
  130. sigemptyset(&ss);
  131. sa.sa_handler = SIG_DFL;
  132. sa.sa_mask = ss;
  133. sa.sa_flags = 0;
  134. sigaction(SIGTERM, &sa, NULL);
  135. sigemptyset(&ss);
  136. sa.sa_handler = SIG_DFL;
  137. sa.sa_mask = ss;
  138. sa.sa_flags = 0;
  139. sigaction(SIGHUP, &sa, NULL);
  140. sigemptyset(&ss);
  141. sa.sa_handler = SIG_DFL;
  142. sa.sa_mask = ss;
  143. sa.sa_flags = 0;
  144. sigaction(SIGINT, &sa, NULL);
  145. sigemptyset(&ss);
  146. sa.sa_handler = SIG_DFL;
  147. sa.sa_mask = ss;
  148. sa.sa_flags = 0;
  149. sigaction(SIGUSR1, &sa, NULL);
  150. sigemptyset(&ss);
  151. sa.sa_handler = SIG_DFL;
  152. sa.sa_mask = ss;
  153. sa.sa_flags = 0;
  154. sigaction(SIGUSR2, &sa, NULL);
  155. #endif
  156. }
  157. #ifdef HAVE_FORK
  158. void
  159. interestingSignals(sigset_t *ss)
  160. {
  161. sigemptyset(ss);
  162. sigaddset(ss, SIGTERM);
  163. sigaddset(ss, SIGHUP);
  164. sigaddset(ss, SIGINT);
  165. sigaddset(ss, SIGUSR1);
  166. sigaddset(ss, SIGUSR2);
  167. }
  168. #endif
  169. void
  170. timeToSleep(struct timeval *time)
  171. {
  172. if(!timeEventQueue) {
  173. time->tv_sec = ~0L;
  174. time->tv_usec = ~0L;
  175. } else {
  176. *time = timeEventQueue->time;
  177. }
  178. }
  179. static TimeEventHandlerPtr
  180. enqueueTimeEvent(TimeEventHandlerPtr event)
  181. {
  182. TimeEventHandlerPtr otherevent;
  183. /* We try to optimise two cases -- the event happens very soon, or
  184. it happens after most of the other events. */
  185. if(timeEventQueue == NULL ||
  186. timeval_cmp(&event->time, &timeEventQueue->time) < 0) {
  187. /* It's the first event */
  188. event->next = timeEventQueue;
  189. event->previous = NULL;
  190. if(timeEventQueue) {
  191. timeEventQueue->previous = event;
  192. } else {
  193. timeEventQueueLast = event;
  194. }
  195. timeEventQueue = event;
  196. } else if(timeval_cmp(&event->time, &timeEventQueueLast->time) >= 0) {
  197. /* It's the last one */
  198. event->next = NULL;
  199. event->previous = timeEventQueueLast;
  200. timeEventQueueLast->next = event;
  201. timeEventQueueLast = event;
  202. } else {
  203. /* Walk from the end */
  204. otherevent = timeEventQueueLast;
  205. while(otherevent->previous &&
  206. timeval_cmp(&event->time, &otherevent->previous->time) < 0) {
  207. otherevent = otherevent->previous;
  208. }
  209. event->next = otherevent;
  210. event->previous = otherevent->previous;
  211. if(otherevent->previous) {
  212. otherevent->previous->next = event;
  213. } else {
  214. timeEventQueue = event;
  215. }
  216. otherevent->previous = event;
  217. }
  218. return event;
  219. }
  220. TimeEventHandlerPtr
  221. scheduleTimeEvent(int seconds,
  222. int (*handler)(TimeEventHandlerPtr), int dsize, void *data)
  223. {
  224. struct timeval when;
  225. TimeEventHandlerPtr event;
  226. if(seconds >= 0) {
  227. when = current_time;
  228. when.tv_sec += seconds;
  229. } else {
  230. when.tv_sec = 0;
  231. when.tv_usec = 0;
  232. }
  233. event = malloc(sizeof(TimeEventHandlerRec) - 1 + dsize);
  234. if(event == NULL) {
  235. do_log(L_ERROR, "Couldn't allocate time event handler -- "
  236. "discarding all objects.\n");
  237. exitFlag = 2;
  238. return NULL;
  239. }
  240. event->time = when;
  241. event->handler = handler;
  242. /* Let the compiler optimise the common case */
  243. if(dsize == sizeof(void*))
  244. memcpy(event->data, data, sizeof(void*));
  245. else if(dsize > 0)
  246. memcpy(event->data, data, dsize);
  247. return enqueueTimeEvent(event);
  248. }
  249. void
  250. cancelTimeEvent(TimeEventHandlerPtr event)
  251. {
  252. if(event == timeEventQueue)
  253. timeEventQueue = event->next;
  254. if(event == timeEventQueueLast)
  255. timeEventQueueLast = event->previous;
  256. if(event->next)
  257. event->next->previous = event->previous;
  258. if(event->previous)
  259. event->previous->next = event->next;
  260. free(event);
  261. }
  262. int
  263. allocateFdEventNum(int fd)
  264. {
  265. int i;
  266. if(fdEventNum < fdEventSize) {
  267. i = fdEventNum;
  268. fdEventNum++;
  269. } else {
  270. struct pollfd *new_poll_fds;
  271. FdEventHandlerPtr *new_fdEvents, *new_fdEventsLast;
  272. int new_size = 3 * fdEventSize / 2 + 1;
  273. new_poll_fds = realloc(poll_fds, new_size * sizeof(struct pollfd));
  274. if(!new_poll_fds)
  275. return -1;
  276. new_fdEvents = realloc(fdEvents, new_size * sizeof(FdEventHandlerPtr));
  277. if(!new_fdEvents)
  278. return -1;
  279. new_fdEventsLast = realloc(fdEventsLast,
  280. new_size * sizeof(FdEventHandlerPtr));
  281. if(!new_fdEventsLast)
  282. return -1;
  283. poll_fds = new_poll_fds;
  284. fdEvents = new_fdEvents;
  285. fdEventsLast = new_fdEventsLast;
  286. fdEventSize = new_size;
  287. i = fdEventNum;
  288. fdEventNum++;
  289. }
  290. poll_fds[i].fd = fd;
  291. poll_fds[i].events = POLLERR | POLLHUP | POLLNVAL;
  292. poll_fds[i].revents = 0;
  293. fdEvents[i] = NULL;
  294. fdEventsLast[i] = NULL;
  295. fds_invalid = 1;
  296. return i;
  297. }
  298. void
  299. deallocateFdEventNum(int i)
  300. {
  301. if(i < fdEventNum - 1) {
  302. memmove(&poll_fds[i], &poll_fds[i + 1],
  303. (fdEventNum - i - 1) * sizeof(struct pollfd));
  304. memmove(&fdEvents[i], &fdEvents[i + 1],
  305. (fdEventNum - i - 1) * sizeof(FdEventHandlerPtr));
  306. memmove(&fdEventsLast[i], &fdEventsLast[i + 1],
  307. (fdEventNum - i - 1) * sizeof(FdEventHandlerPtr));
  308. }
  309. fdEventNum--;
  310. fds_invalid = 1;
  311. }
  312. FdEventHandlerPtr
  313. makeFdEvent(int fd, int poll_events,
  314. int (*handler)(int, FdEventHandlerPtr), int dsize, void *data)
  315. {
  316. FdEventHandlerPtr event;
  317. event = malloc(sizeof(FdEventHandlerRec) - 1 + dsize);
  318. if(event == NULL) {
  319. do_log(L_ERROR, "Couldn't allocate fd event handler -- "
  320. "discarding all objects.\n");
  321. exitFlag = 2;
  322. return NULL;
  323. }
  324. event->fd = fd;
  325. event->poll_events = poll_events;
  326. event->handler = handler;
  327. /* Let the compiler optimise the common cases */
  328. if(dsize == sizeof(void*))
  329. memcpy(event->data, data, sizeof(void*));
  330. else if(dsize == sizeof(StreamRequestRec))
  331. memcpy(event->data, data, sizeof(StreamRequestRec));
  332. else if(dsize > 0)
  333. memcpy(event->data, data, dsize);
  334. return event;
  335. }
  336. FdEventHandlerPtr
  337. registerFdEventHelper(FdEventHandlerPtr event)
  338. {
  339. int i;
  340. int fd = event->fd;
  341. for(i = 0; i < fdEventNum; i++)
  342. if(poll_fds[i].fd == fd)
  343. break;
  344. if(i >= fdEventNum)
  345. i = allocateFdEventNum(fd);
  346. if(i < 0) {
  347. free(event);
  348. return NULL;
  349. }
  350. event->next = NULL;
  351. event->previous = fdEventsLast[i];
  352. if(fdEvents[i] == NULL) {
  353. fdEvents[i] = event;
  354. } else {
  355. fdEventsLast[i]->next = event;
  356. }
  357. fdEventsLast[i] = event;
  358. poll_fds[i].events |= event->poll_events;
  359. return event;
  360. }
  361. FdEventHandlerPtr
  362. registerFdEvent(int fd, int poll_events,
  363. int (*handler)(int, FdEventHandlerPtr), int dsize, void *data)
  364. {
  365. FdEventHandlerPtr event;
  366. event = makeFdEvent(fd, poll_events, handler, dsize, data);
  367. if(event == NULL)
  368. return NULL;
  369. return registerFdEventHelper(event);
  370. }
  371. static int
  372. recomputePollEvents(FdEventHandlerPtr event)
  373. {
  374. int pe = 0;
  375. while(event) {
  376. pe |= event->poll_events;
  377. event = event->next;
  378. }
  379. return pe | POLLERR | POLLHUP | POLLNVAL;
  380. }
  381. static void
  382. unregisterFdEventI(FdEventHandlerPtr event, int i)
  383. {
  384. assert(i < fdEventNum && poll_fds[i].fd == event->fd);
  385. if(fdEvents[i] == event) {
  386. assert(!event->previous);
  387. fdEvents[i] = event->next;
  388. } else {
  389. event->previous->next = event->next;
  390. }
  391. if(fdEventsLast[i] == event) {
  392. assert(!event->next);
  393. fdEventsLast[i] = event->previous;
  394. } else {
  395. event->next->previous = event->previous;
  396. }
  397. free(event);
  398. if(fdEvents[i] == NULL) {
  399. deallocateFdEventNum(i);
  400. } else {
  401. poll_fds[i].events = recomputePollEvents(fdEvents[i]) |
  402. POLLERR | POLLHUP | POLLNVAL;
  403. }
  404. }
  405. void
  406. unregisterFdEvent(FdEventHandlerPtr event)
  407. {
  408. int i;
  409. for(i = 0; i < fdEventNum; i++) {
  410. if(poll_fds[i].fd == event->fd) {
  411. unregisterFdEventI(event, i);
  412. return;
  413. }
  414. }
  415. abort();
  416. }
  417. void
  418. runTimeEventQueue()
  419. {
  420. TimeEventHandlerPtr event;
  421. int done;
  422. while(timeEventQueue &&
  423. timeval_cmp(&timeEventQueue->time, &current_time) <= 0) {
  424. event = timeEventQueue;
  425. timeEventQueue = event->next;
  426. if(timeEventQueue)
  427. timeEventQueue->previous = NULL;
  428. else
  429. timeEventQueueLast = NULL;
  430. done = event->handler(event);
  431. assert(done);
  432. free(event);
  433. }
  434. }
  435. static FdEventHandlerPtr
  436. findEventHelper(int revents, FdEventHandlerPtr events)
  437. {
  438. FdEventHandlerPtr event = events;
  439. while(event) {
  440. if(revents & event->poll_events)
  441. return event;
  442. event = event->next;
  443. }
  444. return NULL;
  445. }
  446. static FdEventHandlerPtr
  447. findEvent(int revents, FdEventHandlerPtr events)
  448. {
  449. FdEventHandlerPtr event;
  450. assert(!(revents & POLLNVAL));
  451. if((revents & POLLHUP) || (revents & POLLERR)) {
  452. event = findEventHelper(POLLOUT, events);
  453. if(event) return event;
  454. event = findEventHelper(POLLIN, events);
  455. if(event) return event;
  456. return NULL;
  457. }
  458. if(revents & POLLOUT) {
  459. event = findEventHelper(POLLOUT, events);
  460. if(event) return event;
  461. }
  462. if(revents & POLLIN) {
  463. event = findEventHelper(POLLIN, events);
  464. if(event) return event;
  465. }
  466. return NULL;
  467. }
  468. typedef struct _FdEventHandlerPoke {
  469. int fd;
  470. int what;
  471. int status;
  472. } FdEventHandlerPokeRec, *FdEventHandlerPokePtr;
  473. static int
  474. pokeFdEventHandler(TimeEventHandlerPtr tevent)
  475. {
  476. FdEventHandlerPokePtr poke = (FdEventHandlerPokePtr)tevent->data;
  477. int fd = poke->fd;
  478. int what = poke->what;
  479. int status = poke->status;
  480. int done;
  481. FdEventHandlerPtr event, next;
  482. int i;
  483. for(i = 0; i < fdEventNum; i++) {
  484. if(poll_fds[i].fd == fd)
  485. break;
  486. }
  487. if(i >= fdEventNum)
  488. return 1;
  489. event = fdEvents[i];
  490. while(event) {
  491. next = event->next;
  492. if(event->poll_events & what) {
  493. done = event->handler(status, event);
  494. if(done) {
  495. if(fds_invalid)
  496. unregisterFdEvent(event);
  497. else
  498. unregisterFdEventI(event, i);
  499. }
  500. if(fds_invalid)
  501. break;
  502. }
  503. event = next;
  504. }
  505. return 1;
  506. }
  507. void
  508. pokeFdEvent(int fd, int status, int what)
  509. {
  510. TimeEventHandlerPtr handler;
  511. FdEventHandlerPokeRec poke;
  512. poke.fd = fd;
  513. poke.status = status;
  514. poke.what = what;
  515. handler = scheduleTimeEvent(0, pokeFdEventHandler,
  516. sizeof(poke), &poke);
  517. if(!handler) {
  518. do_log(L_ERROR, "Couldn't allocate handler.\n");
  519. }
  520. }
  521. int
  522. workToDo()
  523. {
  524. struct timeval sleep_time;
  525. int rc;
  526. if(exitFlag)
  527. return 1;
  528. timeToSleep(&sleep_time);
  529. gettimeofday(&current_time, NULL);
  530. if(timeval_cmp(&sleep_time, &current_time) <= 0)
  531. return 1;
  532. rc = poll(poll_fds, fdEventNum, 0);
  533. if(rc < 0) {
  534. do_log_error(L_ERROR, errno, "Couldn't poll");
  535. return 1;
  536. }
  537. return(rc >= 1);
  538. }
  539. void
  540. eventLoop()
  541. {
  542. struct timeval sleep_time, timeout;
  543. int rc, i, done, n;
  544. FdEventHandlerPtr event;
  545. int fd0;
  546. gettimeofday(&current_time, NULL);
  547. while(1) {
  548. again:
  549. if(exitFlag) {
  550. if(exitFlag < 3)
  551. reopenLog();
  552. if(exitFlag >= 2) {
  553. discardObjects(1, 0);
  554. if(exitFlag >= 3)
  555. return;
  556. free_chunk_arenas();
  557. } else {
  558. writeoutObjects(1);
  559. }
  560. initForbidden();
  561. exitFlag = 0;
  562. }
  563. timeToSleep(&sleep_time);
  564. if(sleep_time.tv_sec == -1) {
  565. rc = poll(poll_fds, fdEventNum,
  566. diskIsClean ? -1 : idleTime * 1000);
  567. } else if(timeval_cmp(&sleep_time, &current_time) <= 0) {
  568. runTimeEventQueue();
  569. continue;
  570. } else {
  571. gettimeofday(&current_time, NULL);
  572. if(timeval_cmp(&sleep_time, &current_time) <= 0) {
  573. runTimeEventQueue();
  574. continue;
  575. } else {
  576. int t;
  577. timeval_minus(&timeout, &sleep_time, &current_time);
  578. t = timeout.tv_sec * 1000 + (timeout.tv_usec + 999) / 1000;
  579. rc = poll(poll_fds, fdEventNum,
  580. diskIsClean ? t : MIN(idleTime * 1000, t));
  581. }
  582. }
  583. gettimeofday(&current_time, NULL);
  584. if(rc < 0) {
  585. if(errno == EINTR) {
  586. continue;
  587. } else if(errno == ENOMEM) {
  588. free_chunk_arenas();
  589. do_log(L_ERROR,
  590. "Couldn't poll: out of memory. "
  591. "Sleeping for one second.\n");
  592. sleep(1);
  593. } else {
  594. do_log_error(L_ERROR, errno, "Couldn't poll");
  595. exitFlag = 3;
  596. }
  597. continue;
  598. }
  599. if(rc == 0) {
  600. if(!diskIsClean) {
  601. timeToSleep(&sleep_time);
  602. if(timeval_cmp(&sleep_time, &current_time) > 0)
  603. writeoutObjects(0);
  604. }
  605. continue;
  606. }
  607. /* Rather than tracking all changes to the in-memory cache, we
  608. assume that something changed whenever we see any activity. */
  609. diskIsClean = 0;
  610. fd0 =
  611. (current_time.tv_usec ^ (current_time.tv_usec >> 16)) % fdEventNum;
  612. n = rc;
  613. for(i = 0; i < fdEventNum; i++) {
  614. int j = (i + fd0) % fdEventNum;
  615. if(n <= 0)
  616. break;
  617. if(poll_fds[j].revents) {
  618. n--;
  619. event = findEvent(poll_fds[j].revents, fdEvents[j]);
  620. if(!event)
  621. continue;
  622. done = event->handler(0, event);
  623. if(done) {
  624. if(fds_invalid)
  625. unregisterFdEvent(event);
  626. else
  627. unregisterFdEventI(event, j);
  628. }
  629. if(fds_invalid) {
  630. fds_invalid = 0;
  631. goto again;
  632. }
  633. }
  634. }
  635. }
  636. }
  637. void
  638. initCondition(ConditionPtr condition)
  639. {
  640. condition->handlers = NULL;
  641. }
  642. ConditionPtr
  643. makeCondition(void)
  644. {
  645. ConditionPtr condition;
  646. condition = malloc(sizeof(ConditionRec));
  647. if(condition == NULL)
  648. return NULL;
  649. initCondition(condition);
  650. return condition;
  651. }
  652. ConditionHandlerPtr
  653. conditionWait(ConditionPtr condition,
  654. int (*handler)(int, ConditionHandlerPtr),
  655. int dsize, void *data)
  656. {
  657. ConditionHandlerPtr chandler;
  658. assert(!in_signalCondition);
  659. chandler = malloc(sizeof(ConditionHandlerRec) - 1 + dsize);
  660. if(!chandler)
  661. return NULL;
  662. chandler->condition = condition;
  663. chandler->handler = handler;
  664. /* Let the compiler optimise the common case */
  665. if(dsize == sizeof(void*))
  666. memcpy(chandler->data, data, sizeof(void*));
  667. else if(dsize > 0)
  668. memcpy(chandler->data, data, dsize);
  669. if(condition->handlers)
  670. condition->handlers->previous = chandler;
  671. chandler->next = condition->handlers;
  672. chandler->previous = NULL;
  673. condition->handlers = chandler;
  674. return chandler;
  675. }
  676. void
  677. unregisterConditionHandler(ConditionHandlerPtr handler)
  678. {
  679. ConditionPtr condition = handler->condition;
  680. assert(!in_signalCondition);
  681. if(condition->handlers == handler)
  682. condition->handlers = condition->handlers->next;
  683. if(handler->next)
  684. handler->next->previous = handler->previous;
  685. if(handler->previous)
  686. handler->previous->next = handler->next;
  687. free(handler);
  688. }
  689. void
  690. abortConditionHandler(ConditionHandlerPtr handler)
  691. {
  692. int done;
  693. done = handler->handler(-1, handler);
  694. assert(done);
  695. unregisterConditionHandler(handler);
  696. }
  697. void
  698. signalCondition(ConditionPtr condition)
  699. {
  700. ConditionHandlerPtr handler;
  701. int done;
  702. assert(!in_signalCondition);
  703. in_signalCondition++;
  704. handler = condition->handlers;
  705. while(handler) {
  706. ConditionHandlerPtr next = handler->next;
  707. done = handler->handler(0, handler);
  708. if(done) {
  709. if(handler == condition->handlers)
  710. condition->handlers = next;
  711. if(next)
  712. next->previous = handler->previous;
  713. if(handler->previous)
  714. handler->previous->next = next;
  715. else
  716. condition->handlers = next;
  717. free(handler);
  718. }
  719. handler = next;
  720. }
  721. in_signalCondition--;
  722. }
  723. void
  724. polipoExit()
  725. {
  726. exitFlag = 3;
  727. }