… | |
… | |
39 | static int have_monotonic; /* runtime */ |
39 | static int have_monotonic; /* runtime */ |
40 | |
40 | |
41 | static ev_tstamp method_fudge; /* stupid epoll-returns-early bug */ |
41 | static ev_tstamp method_fudge; /* stupid epoll-returns-early bug */ |
42 | static void (*method_modify)(int fd, int oev, int nev); |
42 | static void (*method_modify)(int fd, int oev, int nev); |
43 | static void (*method_poll)(ev_tstamp timeout); |
43 | static void (*method_poll)(ev_tstamp timeout); |
|
|
44 | |
|
|
45 | /*****************************************************************************/ |
44 | |
46 | |
45 | ev_tstamp |
47 | ev_tstamp |
46 | ev_time (void) |
48 | ev_time (void) |
47 | { |
49 | { |
48 | #if HAVE_REALTIME |
50 | #if HAVE_REALTIME |
… | |
… | |
79 | base = realloc (base, sizeof (*base) * (newcnt)); \ |
81 | base = realloc (base, sizeof (*base) * (newcnt)); \ |
80 | init (base + cur, newcnt - cur); \ |
82 | init (base + cur, newcnt - cur); \ |
81 | cur = newcnt; \ |
83 | cur = newcnt; \ |
82 | } |
84 | } |
83 | |
85 | |
|
|
86 | /*****************************************************************************/ |
|
|
87 | |
84 | typedef struct |
88 | typedef struct |
85 | { |
89 | { |
86 | struct ev_io *head; |
90 | struct ev_io *head; |
87 | unsigned char wev, rev; /* want, received event set */ |
91 | unsigned char wev, rev; /* want, received event set */ |
88 | } ANFD; |
92 | } ANFD; |
… | |
… | |
135 | if (ev) |
139 | if (ev) |
136 | event ((struct ev_watcher *)w, ev); |
140 | event ((struct ev_watcher *)w, ev); |
137 | } |
141 | } |
138 | } |
142 | } |
139 | |
143 | |
|
|
144 | static void |
|
|
145 | queue_events (struct ev_watcher **events, int eventcnt, int type) |
|
|
146 | { |
|
|
147 | int i; |
|
|
148 | |
|
|
149 | for (i = 0; i < eventcnt; ++i) |
|
|
150 | event (events [i], type); |
|
|
151 | } |
|
|
152 | |
|
|
153 | /*****************************************************************************/ |
|
|
154 | |
140 | static struct ev_timer **atimers; |
155 | static struct ev_timer **atimers; |
141 | static int atimermax, atimercnt; |
156 | static int atimermax, atimercnt; |
142 | |
157 | |
143 | static struct ev_timer **rtimers; |
158 | static struct ev_timer **rtimers; |
144 | static int rtimermax, rtimercnt; |
159 | static int rtimermax, rtimercnt; |
… | |
… | |
181 | } |
196 | } |
182 | |
197 | |
183 | timers [k] = w; |
198 | timers [k] = w; |
184 | timers [k]->active = k + 1; |
199 | timers [k]->active = k + 1; |
185 | } |
200 | } |
|
|
201 | |
|
|
202 | /*****************************************************************************/ |
186 | |
203 | |
187 | typedef struct |
204 | typedef struct |
188 | { |
205 | { |
189 | struct ev_signal *head; |
206 | struct ev_signal *head; |
190 | sig_atomic_t gotsig; |
207 | sig_atomic_t gotsig; |
… | |
… | |
250 | fcntl (sigpipe [1], F_SETFL, O_NONBLOCK); |
267 | fcntl (sigpipe [1], F_SETFL, O_NONBLOCK); |
251 | |
268 | |
252 | evio_set (&sigev, sigpipe [0], EV_READ); |
269 | evio_set (&sigev, sigpipe [0], EV_READ); |
253 | evio_start (&sigev); |
270 | evio_start (&sigev); |
254 | } |
271 | } |
|
|
272 | |
|
|
273 | /*****************************************************************************/ |
|
|
274 | |
|
|
275 | static struct ev_idle **idles; |
|
|
276 | static int idlemax, idlecnt; |
|
|
277 | |
|
|
278 | static struct ev_check **checks; |
|
|
279 | static int checkmax, checkcnt; |
|
|
280 | |
|
|
281 | /*****************************************************************************/ |
255 | |
282 | |
256 | #if HAVE_EPOLL |
283 | #if HAVE_EPOLL |
257 | # include "ev_epoll.c" |
284 | # include "ev_epoll.c" |
258 | #endif |
285 | #endif |
259 | #if HAVE_SELECT |
286 | #if HAVE_SELECT |
… | |
… | |
292 | } |
319 | } |
293 | |
320 | |
294 | return ev_method; |
321 | return ev_method; |
295 | } |
322 | } |
296 | |
323 | |
|
|
324 | /*****************************************************************************/ |
|
|
325 | |
297 | void ev_prefork (void) |
326 | void ev_prefork (void) |
298 | { |
327 | { |
299 | } |
328 | } |
300 | |
329 | |
301 | void ev_postfork_parent (void) |
330 | void ev_postfork_parent (void) |
… | |
… | |
314 | close (sigpipe [1]); |
343 | close (sigpipe [1]); |
315 | pipe (sigpipe); |
344 | pipe (sigpipe); |
316 | siginit (); |
345 | siginit (); |
317 | } |
346 | } |
318 | |
347 | |
|
|
348 | /*****************************************************************************/ |
|
|
349 | |
319 | static void |
350 | static void |
320 | fd_reify (void) |
351 | fd_reify (void) |
321 | { |
352 | { |
322 | int i; |
353 | int i; |
323 | |
354 | |
… | |
… | |
435 | void ev_loop (int flags) |
466 | void ev_loop (int flags) |
436 | { |
467 | { |
437 | double block; |
468 | double block; |
438 | ev_loop_done = flags & EVLOOP_ONESHOT; |
469 | ev_loop_done = flags & EVLOOP_ONESHOT; |
439 | |
470 | |
|
|
471 | if (checkcnt) |
|
|
472 | { |
|
|
473 | queue_events (checks, checkcnt, EV_CHECK); |
|
|
474 | call_pending (); |
|
|
475 | } |
|
|
476 | |
440 | do |
477 | do |
441 | { |
478 | { |
442 | /* update fd-related kernel structures */ |
479 | /* update fd-related kernel structures */ |
443 | fd_reify (); |
480 | fd_reify (); |
444 | |
481 | |
445 | /* calculate blocking time */ |
482 | /* calculate blocking time */ |
446 | if (flags & EVLOOP_NONBLOCK) |
483 | if (flags & EVLOOP_NONBLOCK || idlecnt) |
447 | block = 0.; |
484 | block = 0.; |
448 | else |
485 | else |
449 | { |
486 | { |
450 | block = MAX_BLOCKTIME; |
487 | block = MAX_BLOCKTIME; |
451 | |
488 | |
… | |
… | |
467 | method_poll (block); |
504 | method_poll (block); |
468 | |
505 | |
469 | /* update ev_now, do magic */ |
506 | /* update ev_now, do magic */ |
470 | time_update (); |
507 | time_update (); |
471 | |
508 | |
472 | /* put pending timers into pendign queue and reschedule them */ |
509 | /* queue pending timers and reschedule them */ |
473 | /* absolute timers first */ |
510 | /* absolute timers first */ |
474 | timers_reify (atimers, atimercnt, ev_now); |
511 | timers_reify (atimers, atimercnt, ev_now); |
475 | /* relative timers second */ |
512 | /* relative timers second */ |
476 | timers_reify (rtimers, rtimercnt, now); |
513 | timers_reify (rtimers, rtimercnt, now); |
477 | |
514 | |
|
|
515 | /* queue idle watchers unless io or timers are pending */ |
|
|
516 | if (!pendingcnt) |
|
|
517 | queue_events (idles, idlecnt, EV_IDLE); |
|
|
518 | |
|
|
519 | /* queue check and possibly idle watchers */ |
|
|
520 | queue_events (checks, checkcnt, EV_CHECK); |
|
|
521 | |
478 | call_pending (); |
522 | call_pending (); |
479 | } |
523 | } |
480 | while (!ev_loop_done); |
524 | while (!ev_loop_done); |
481 | } |
525 | } |
|
|
526 | |
|
|
527 | /*****************************************************************************/ |
482 | |
528 | |
483 | static void |
529 | static void |
484 | wlist_add (struct ev_watcher_list **head, struct ev_watcher_list *elem) |
530 | wlist_add (struct ev_watcher_list **head, struct ev_watcher_list *elem) |
485 | { |
531 | { |
486 | elem->next = *head; |
532 | elem->next = *head; |
… | |
… | |
516 | pendings [w->pending - 1].w = 0; |
562 | pendings [w->pending - 1].w = 0; |
517 | |
563 | |
518 | w->active = 0; |
564 | w->active = 0; |
519 | /* nop */ |
565 | /* nop */ |
520 | } |
566 | } |
|
|
567 | |
|
|
568 | /*****************************************************************************/ |
521 | |
569 | |
522 | void |
570 | void |
523 | evio_start (struct ev_io *w) |
571 | evio_start (struct ev_io *w) |
524 | { |
572 | { |
525 | if (ev_is_active (w)) |
573 | if (ev_is_active (w)) |
… | |
… | |
636 | |
684 | |
637 | if (!signals [w->signum - 1].head) |
685 | if (!signals [w->signum - 1].head) |
638 | signal (w->signum, SIG_DFL); |
686 | signal (w->signum, SIG_DFL); |
639 | } |
687 | } |
640 | |
688 | |
|
|
689 | void evidle_start (struct ev_idle *w) |
|
|
690 | { |
|
|
691 | if (ev_is_active (w)) |
|
|
692 | return; |
|
|
693 | |
|
|
694 | ev_start ((struct ev_watcher *)w, ++idlecnt); |
|
|
695 | array_needsize (idles, idlemax, idlecnt, ); |
|
|
696 | idles [idlecnt - 1] = w; |
|
|
697 | } |
|
|
698 | |
|
|
699 | void evidle_stop (struct ev_idle *w) |
|
|
700 | { |
|
|
701 | idles [w->active - 1] = idles [--idlecnt]; |
|
|
702 | ev_stop ((struct ev_watcher *)w); |
|
|
703 | } |
|
|
704 | |
|
|
705 | void evcheck_start (struct ev_check *w) |
|
|
706 | { |
|
|
707 | if (ev_is_active (w)) |
|
|
708 | return; |
|
|
709 | |
|
|
710 | ev_start ((struct ev_watcher *)w, ++checkcnt); |
|
|
711 | array_needsize (checks, checkmax, checkcnt, ); |
|
|
712 | checks [checkcnt - 1] = w; |
|
|
713 | } |
|
|
714 | |
|
|
715 | void evcheck_stop (struct ev_check *w) |
|
|
716 | { |
|
|
717 | checks [w->active - 1] = checks [--checkcnt]; |
|
|
718 | ev_stop ((struct ev_watcher *)w); |
|
|
719 | } |
|
|
720 | |
641 | /*****************************************************************************/ |
721 | /*****************************************************************************/ |
642 | #if 1 |
722 | #if 1 |
643 | |
723 | |
644 | static void |
724 | static void |
645 | sin_cb (struct ev_io *w, int revents) |
725 | sin_cb (struct ev_io *w, int revents) |
… | |
… | |
657 | |
737 | |
658 | static void |
738 | static void |
659 | scb (struct ev_signal *w, int revents) |
739 | scb (struct ev_signal *w, int revents) |
660 | { |
740 | { |
661 | fprintf (stderr, "signal %x,%d\n", revents, w->signum); |
741 | fprintf (stderr, "signal %x,%d\n", revents, w->signum); |
|
|
742 | } |
|
|
743 | |
|
|
744 | static void |
|
|
745 | gcb (struct ev_signal *w, int revents) |
|
|
746 | { |
|
|
747 | fprintf (stderr, "generic %x\n", revents); |
662 | } |
748 | } |
663 | |
749 | |
664 | int main (void) |
750 | int main (void) |
665 | { |
751 | { |
666 | struct ev_io sin; |
752 | struct ev_io sin; |
… | |
… | |
694 | struct ev_signal sig; |
780 | struct ev_signal sig; |
695 | evw_init (&sig, scb, 65535); |
781 | evw_init (&sig, scb, 65535); |
696 | evsignal_set (&sig, SIGQUIT); |
782 | evsignal_set (&sig, SIGQUIT); |
697 | evsignal_start (&sig); |
783 | evsignal_start (&sig); |
698 | |
784 | |
|
|
785 | struct ev_check cw; |
|
|
786 | evw_init (&cw, gcb, 0); |
|
|
787 | evcheck_start (&cw); |
|
|
788 | |
|
|
789 | struct ev_idle iw; |
|
|
790 | evw_init (&iw, gcb, 0); |
|
|
791 | evidle_start (&iw); |
|
|
792 | |
699 | ev_loop (0); |
793 | ev_loop (0); |
700 | |
794 | |
701 | return 0; |
795 | return 0; |
702 | } |
796 | } |
703 | |
797 | |