|
|
1 | /* |
|
|
2 | * Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de> |
|
|
3 | * All rights reserved. |
|
|
4 | * |
|
|
5 | * Redistribution and use in source and binary forms, with or without |
|
|
6 | * modification, are permitted provided that the following conditions are |
|
|
7 | * met: |
|
|
8 | * |
|
|
9 | * * Redistributions of source code must retain the above copyright |
|
|
10 | * notice, this list of conditions and the following disclaimer. |
|
|
11 | * |
|
|
12 | * * Redistributions in binary form must reproduce the above |
|
|
13 | * copyright notice, this list of conditions and the following |
|
|
14 | * disclaimer in the documentation and/or other materials provided |
|
|
15 | * with the distribution. |
|
|
16 | * |
|
|
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
|
18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
|
19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
|
20 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
|
21 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
|
22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
|
23 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
|
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
|
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
|
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
|
27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
28 | */ |
|
|
29 | |
1 | #include <math.h> |
30 | #include <math.h> |
2 | #include <stdlib.h> |
31 | #include <stdlib.h> |
3 | #include <unistd.h> |
32 | #include <unistd.h> |
4 | #include <fcntl.h> |
33 | #include <fcntl.h> |
5 | #include <signal.h> |
34 | #include <signal.h> |
… | |
… | |
9 | |
38 | |
10 | #include <assert.h> |
39 | #include <assert.h> |
11 | #include <errno.h> |
40 | #include <errno.h> |
12 | #include <sys/time.h> |
41 | #include <sys/time.h> |
13 | #include <time.h> |
42 | #include <time.h> |
14 | |
|
|
15 | #define HAVE_EPOLL 1 |
|
|
16 | |
43 | |
17 | #ifndef HAVE_MONOTONIC |
44 | #ifndef HAVE_MONOTONIC |
18 | # ifdef CLOCK_MONOTONIC |
45 | # ifdef CLOCK_MONOTONIC |
19 | # define HAVE_MONOTONIC 1 |
46 | # define HAVE_MONOTONIC 1 |
20 | # endif |
47 | # endif |
… | |
… | |
159 | |
186 | |
160 | for (i = 0; i < eventcnt; ++i) |
187 | for (i = 0; i < eventcnt; ++i) |
161 | event (events [i], type); |
188 | event (events [i], type); |
162 | } |
189 | } |
163 | |
190 | |
|
|
191 | /* called on EBADF to verify fds */ |
|
|
192 | static void |
|
|
193 | fd_recheck () |
|
|
194 | { |
|
|
195 | int fd; |
|
|
196 | |
|
|
197 | for (fd = 0; fd < anfdmax; ++fd) |
|
|
198 | if (anfds [fd].wev) |
|
|
199 | if (fcntl (fd, F_GETFD) == -1 && errno == EBADF) |
|
|
200 | while (anfds [fd].head) |
|
|
201 | evio_stop (anfds [fd].head); |
|
|
202 | } |
|
|
203 | |
164 | /*****************************************************************************/ |
204 | /*****************************************************************************/ |
165 | |
205 | |
166 | static struct ev_timer **timers; |
206 | static struct ev_timer **timers; |
167 | static int timermax, timercnt; |
207 | static int timermax, timercnt; |
168 | |
208 | |
… | |
… | |
283 | |
323 | |
284 | /*****************************************************************************/ |
324 | /*****************************************************************************/ |
285 | |
325 | |
286 | static struct ev_idle **idles; |
326 | static struct ev_idle **idles; |
287 | static int idlemax, idlecnt; |
327 | static int idlemax, idlecnt; |
|
|
328 | |
|
|
329 | static struct ev_prepare **prepares; |
|
|
330 | static int preparemax, preparecnt; |
288 | |
331 | |
289 | static struct ev_check **checks; |
332 | static struct ev_check **checks; |
290 | static int checkmax, checkcnt; |
333 | static int checkmax, checkcnt; |
291 | |
334 | |
292 | /*****************************************************************************/ |
335 | /*****************************************************************************/ |
… | |
… | |
387 | } |
430 | } |
388 | |
431 | |
389 | static void |
432 | static void |
390 | call_pending () |
433 | call_pending () |
391 | { |
434 | { |
392 | int i; |
435 | while (pendingcnt) |
393 | |
|
|
394 | for (i = 0; i < pendingcnt; ++i) |
|
|
395 | { |
436 | { |
396 | ANPENDING *p = pendings + i; |
437 | ANPENDING *p = pendings + --pendingcnt; |
397 | |
438 | |
398 | if (p->w) |
439 | if (p->w) |
399 | { |
440 | { |
400 | p->w->pending = 0; |
441 | p->w->pending = 0; |
401 | p->w->cb (p->w, p->events); |
442 | p->w->cb (p->w, p->events); |
402 | } |
443 | } |
403 | } |
444 | } |
404 | |
|
|
405 | pendingcnt = 0; |
|
|
406 | } |
445 | } |
407 | |
446 | |
408 | static void |
447 | static void |
409 | timers_reify () |
448 | timers_reify () |
410 | { |
449 | { |
… | |
… | |
517 | void ev_loop (int flags) |
556 | void ev_loop (int flags) |
518 | { |
557 | { |
519 | double block; |
558 | double block; |
520 | ev_loop_done = flags & EVLOOP_ONESHOT ? 1 : 0; |
559 | ev_loop_done = flags & EVLOOP_ONESHOT ? 1 : 0; |
521 | |
560 | |
522 | if (checkcnt) |
|
|
523 | { |
|
|
524 | queue_events ((W *)checks, checkcnt, EV_CHECK); |
|
|
525 | call_pending (); |
|
|
526 | } |
|
|
527 | |
|
|
528 | do |
561 | do |
529 | { |
562 | { |
|
|
563 | /* queue check watchers (and execute them) */ |
|
|
564 | if (checkcnt) |
|
|
565 | { |
|
|
566 | queue_events ((W *)prepares, preparecnt, EV_PREPARE); |
|
|
567 | call_pending (); |
|
|
568 | } |
|
|
569 | |
530 | /* update fd-related kernel structures */ |
570 | /* update fd-related kernel structures */ |
531 | fd_reify (); |
571 | fd_reify (); |
532 | |
572 | |
533 | /* calculate blocking time */ |
573 | /* calculate blocking time */ |
534 | |
574 | |
… | |
… | |
560 | |
600 | |
561 | /* update ev_now, do magic */ |
601 | /* update ev_now, do magic */ |
562 | time_update (); |
602 | time_update (); |
563 | |
603 | |
564 | /* queue pending timers and reschedule them */ |
604 | /* queue pending timers and reschedule them */ |
|
|
605 | timers_reify (); /* relative timers called last */ |
565 | periodics_reify (); /* absolute timers first */ |
606 | periodics_reify (); /* absolute timers called first */ |
566 | timers_reify (); /* relative timers second */ |
|
|
567 | |
607 | |
568 | /* queue idle watchers unless io or timers are pending */ |
608 | /* queue idle watchers unless io or timers are pending */ |
569 | if (!pendingcnt) |
609 | if (!pendingcnt) |
570 | queue_events ((W *)idles, idlecnt, EV_IDLE); |
610 | queue_events ((W *)idles, idlecnt, EV_IDLE); |
571 | |
611 | |
572 | /* queue check and possibly idle watchers */ |
612 | /* queue check watchers, to be executed first */ |
|
|
613 | if (checkcnt) |
573 | queue_events ((W *)checks, checkcnt, EV_CHECK); |
614 | queue_events ((W *)checks, checkcnt, EV_CHECK); |
574 | |
615 | |
575 | call_pending (); |
616 | call_pending (); |
576 | } |
617 | } |
577 | while (!ev_loop_done); |
618 | while (!ev_loop_done); |
578 | |
619 | |
… | |
… | |
794 | ev_clear ((W)w); |
835 | ev_clear ((W)w); |
795 | if (ev_is_active (w)) |
836 | if (ev_is_active (w)) |
796 | return; |
837 | return; |
797 | |
838 | |
798 | idles [w->active - 1] = idles [--idlecnt]; |
839 | idles [w->active - 1] = idles [--idlecnt]; |
|
|
840 | ev_stop ((W)w); |
|
|
841 | } |
|
|
842 | |
|
|
843 | void evprepare_start (struct ev_prepare *w) |
|
|
844 | { |
|
|
845 | if (ev_is_active (w)) |
|
|
846 | return; |
|
|
847 | |
|
|
848 | ev_start ((W)w, ++preparecnt); |
|
|
849 | array_needsize (prepares, preparemax, preparecnt, ); |
|
|
850 | prepares [preparecnt - 1] = w; |
|
|
851 | } |
|
|
852 | |
|
|
853 | void evprepare_stop (struct ev_prepare *w) |
|
|
854 | { |
|
|
855 | ev_clear ((W)w); |
|
|
856 | if (ev_is_active (w)) |
|
|
857 | return; |
|
|
858 | |
|
|
859 | prepares [w->active - 1] = prepares [--preparecnt]; |
799 | ev_stop ((W)w); |
860 | ev_stop ((W)w); |
800 | } |
861 | } |
801 | |
862 | |
802 | void evcheck_start (struct ev_check *w) |
863 | void evcheck_start (struct ev_check *w) |
803 | { |
864 | { |