… | |
… | |
33 | |
33 | |
34 | #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
34 | #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
35 | #define MAX_BLOCKTIME 60. |
35 | #define MAX_BLOCKTIME 60. |
36 | |
36 | |
37 | #include "ev.h" |
37 | #include "ev.h" |
38 | |
|
|
39 | struct ev_watcher { |
|
|
40 | EV_WATCHER (ev_watcher); |
|
|
41 | }; |
|
|
42 | |
|
|
43 | struct ev_watcher_list { |
|
|
44 | EV_WATCHER_LIST (ev_watcher_list); |
|
|
45 | }; |
|
|
46 | |
|
|
47 | struct ev_watcher_time { |
|
|
48 | EV_WATCHER_TIME (ev_watcher_time); |
|
|
49 | }; |
|
|
50 | |
38 | |
51 | typedef struct ev_watcher *W; |
39 | typedef struct ev_watcher *W; |
52 | typedef struct ev_watcher_list *WL; |
40 | typedef struct ev_watcher_list *WL; |
53 | typedef struct ev_watcher_time *WT; |
41 | typedef struct ev_watcher_time *WT; |
54 | |
42 | |
… | |
… | |
455 | event ((W)w, EV_TIMEOUT); |
443 | event ((W)w, EV_TIMEOUT); |
456 | } |
444 | } |
457 | } |
445 | } |
458 | |
446 | |
459 | static void |
447 | static void |
460 | time_jump (ev_tstamp diff) |
448 | periodics_reschedule (ev_tstamp diff) |
461 | { |
449 | { |
462 | int i; |
450 | int i; |
463 | |
451 | |
464 | /* adjust periodics */ |
452 | /* adjust periodics after time jump */ |
465 | for (i = 0; i < periodiccnt; ++i) |
453 | for (i = 0; i < periodiccnt; ++i) |
466 | { |
454 | { |
467 | struct ev_periodic *w = periodics [i]; |
455 | struct ev_periodic *w = periodics [i]; |
468 | |
456 | |
469 | if (w->interval) |
457 | if (w->interval) |
… | |
… | |
477 | |
465 | |
478 | i = 0; /* restart loop, inefficient, but time jumps should be rare */ |
466 | i = 0; /* restart loop, inefficient, but time jumps should be rare */ |
479 | } |
467 | } |
480 | } |
468 | } |
481 | } |
469 | } |
482 | |
|
|
483 | /* adjust timers. this is easy, as the offset is the same for all */ |
|
|
484 | for (i = 0; i < timercnt; ++i) |
|
|
485 | timers [i]->at += diff; |
|
|
486 | } |
470 | } |
487 | |
471 | |
488 | static void |
472 | static void |
489 | time_update () |
473 | time_update () |
490 | { |
474 | { |
… | |
… | |
505 | return; /* all is well */ |
489 | return; /* all is well */ |
506 | |
490 | |
507 | ev_now = ev_time (); |
491 | ev_now = ev_time (); |
508 | } |
492 | } |
509 | |
493 | |
510 | time_jump (diff - odiff); |
494 | periodics_reschedule (diff - odiff); |
|
|
495 | /* no timer adjustment, as the monotonic clock doesn't jump */ |
511 | } |
496 | } |
512 | else |
497 | else |
513 | { |
498 | { |
514 | if (now > ev_now || now < ev_now - MAX_BLOCKTIME - MIN_TIMEJUMP) |
499 | if (now > ev_now || now < ev_now - MAX_BLOCKTIME - MIN_TIMEJUMP) |
515 | time_jump (ev_now - now); |
500 | { |
|
|
501 | periodics_reschedule (ev_now - now); |
|
|
502 | |
|
|
503 | /* adjust timers. this is easy, as the offset is the same for all */ |
|
|
504 | for (i = 0; i < timercnt; ++i) |
|
|
505 | timers [i]->at += diff; |
|
|
506 | } |
516 | |
507 | |
517 | now = ev_now; |
508 | now = ev_now; |
518 | } |
509 | } |
519 | } |
510 | } |
520 | |
511 | |
521 | int ev_loop_done; |
512 | int ev_loop_done; |
522 | |
513 | |
523 | void ev_loop (int flags) |
514 | void ev_loop (int flags) |
524 | { |
515 | { |
525 | double block; |
516 | double block; |
526 | ev_loop_done = flags & EVLOOP_ONESHOT; |
517 | ev_loop_done = flags & EVLOOP_ONESHOT ? 1 : 0; |
527 | |
518 | |
528 | if (checkcnt) |
519 | if (checkcnt) |
529 | { |
520 | { |
530 | queue_events ((W *)checks, checkcnt, EV_CHECK); |
521 | queue_events ((W *)checks, checkcnt, EV_CHECK); |
531 | call_pending (); |
522 | call_pending (); |
… | |
… | |
579 | queue_events ((W *)checks, checkcnt, EV_CHECK); |
570 | queue_events ((W *)checks, checkcnt, EV_CHECK); |
580 | |
571 | |
581 | call_pending (); |
572 | call_pending (); |
582 | } |
573 | } |
583 | while (!ev_loop_done); |
574 | while (!ev_loop_done); |
|
|
575 | |
|
|
576 | if (ev_loop_done != 2) |
|
|
577 | ev_loop_done = 0; |
584 | } |
578 | } |
585 | |
579 | |
586 | /*****************************************************************************/ |
580 | /*****************************************************************************/ |
587 | |
581 | |
588 | static void |
582 | static void |
… | |
… | |
663 | if (ev_is_active (w)) |
657 | if (ev_is_active (w)) |
664 | return; |
658 | return; |
665 | |
659 | |
666 | w->at += now; |
660 | w->at += now; |
667 | |
661 | |
|
|
662 | assert (("timer repeat value less than zero not allowed", w->repeat >= 0.)); |
|
|
663 | |
668 | ev_start ((W)w, ++timercnt); |
664 | ev_start ((W)w, ++timercnt); |
669 | array_needsize (timers, timermax, timercnt, ); |
665 | array_needsize (timers, timermax, timercnt, ); |
670 | timers [timercnt - 1] = w; |
666 | timers [timercnt - 1] = w; |
671 | upheap ((WT *)timers, timercnt - 1); |
667 | upheap ((WT *)timers, timercnt - 1); |
672 | } |
668 | } |
… | |
… | |
689 | void |
685 | void |
690 | evperiodic_start (struct ev_periodic *w) |
686 | evperiodic_start (struct ev_periodic *w) |
691 | { |
687 | { |
692 | if (ev_is_active (w)) |
688 | if (ev_is_active (w)) |
693 | return; |
689 | return; |
|
|
690 | |
|
|
691 | assert (("periodic interval value less than zero not allowed", w->interval >= 0.)); |
694 | |
692 | |
695 | /* this formula differs from the one in periodic_reify because we do not always round up */ |
693 | /* this formula differs from the one in periodic_reify because we do not always round up */ |
696 | if (w->interval) |
694 | if (w->interval) |
697 | w->at += ceil ((ev_now - w->at) / w->interval) * w->interval; |
695 | w->at += ceil ((ev_now - w->at) / w->interval) * w->interval; |
698 | |
696 | |
… | |
… | |
782 | ev_stop ((W)w); |
780 | ev_stop ((W)w); |
783 | } |
781 | } |
784 | |
782 | |
785 | /*****************************************************************************/ |
783 | /*****************************************************************************/ |
786 | |
784 | |
787 | #if 1 |
785 | #if 0 |
788 | |
786 | |
789 | struct ev_io wio; |
787 | struct ev_io wio; |
790 | |
788 | |
791 | static void |
789 | static void |
792 | sin_cb (struct ev_io *w, int revents) |
790 | sin_cb (struct ev_io *w, int revents) |