ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev.c
(Generate patch)

Comparing libev/ev.c (file contents):
Revision 1.12 by root, Wed Oct 31 09:23:17 2007 UTC vs.
Revision 1.15 by root, Wed Oct 31 11:56:34 2007 UTC

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
39struct ev_watcher {
40 EV_WATCHER (ev_watcher);
41};
42
43struct ev_watcher_list {
44 EV_WATCHER_LIST (ev_watcher_list);
45};
46
47struct ev_watcher_time {
48 EV_WATCHER_TIME (ev_watcher_time);
49};
50 38
51typedef struct ev_watcher *W; 39typedef struct ev_watcher *W;
52typedef struct ev_watcher_list *WL; 40typedef struct ev_watcher_list *WL;
53typedef struct ev_watcher_time *WT; 41typedef struct ev_watcher_time *WT;
54 42
95 83
96#define array_needsize(base,cur,cnt,init) \ 84#define array_needsize(base,cur,cnt,init) \
97 if ((cnt) > cur) \ 85 if ((cnt) > cur) \
98 { \ 86 { \
99 int newcnt = cur ? cur << 1 : 16; \ 87 int newcnt = cur ? cur << 1 : 16; \
100 fprintf (stderr, "resize(" # base ") from %d to %d\n", cur, newcnt);\
101 base = realloc (base, sizeof (*base) * (newcnt)); \ 88 base = realloc (base, sizeof (*base) * (newcnt)); \
102 init (base + cur, newcnt - cur); \ 89 init (base + cur, newcnt - cur); \
103 cur = newcnt; \ 90 cur = newcnt; \
104 } 91 }
105 92
455 event ((W)w, EV_TIMEOUT); 442 event ((W)w, EV_TIMEOUT);
456 } 443 }
457} 444}
458 445
459static void 446static void
460time_jump (ev_tstamp diff) 447periodics_reschedule (ev_tstamp diff)
461{ 448{
462 int i; 449 int i;
463 450
464 /* adjust periodics */ 451 /* adjust periodics after time jump */
465 for (i = 0; i < periodiccnt; ++i) 452 for (i = 0; i < periodiccnt; ++i)
466 { 453 {
467 struct ev_periodic *w = periodics [i]; 454 struct ev_periodic *w = periodics [i];
468 455
469 if (w->interval) 456 if (w->interval)
477 464
478 i = 0; /* restart loop, inefficient, but time jumps should be rare */ 465 i = 0; /* restart loop, inefficient, but time jumps should be rare */
479 } 466 }
480 } 467 }
481 } 468 }
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} 469}
487 470
488static void 471static void
489time_update () 472time_update ()
490{ 473{
505 return; /* all is well */ 488 return; /* all is well */
506 489
507 ev_now = ev_time (); 490 ev_now = ev_time ();
508 } 491 }
509 492
510 time_jump (diff - odiff); 493 periodics_reschedule (diff - odiff);
494 /* no timer adjustment, as the monotonic clock doesn't jump */
511 } 495 }
512 else 496 else
513 { 497 {
514 if (now > ev_now || now < ev_now - MAX_BLOCKTIME - MIN_TIMEJUMP) 498 if (now > ev_now || now < ev_now - MAX_BLOCKTIME - MIN_TIMEJUMP)
515 time_jump (ev_now - now); 499 {
500 periodics_reschedule (ev_now - now);
501
502 /* adjust timers. this is easy, as the offset is the same for all */
503 for (i = 0; i < timercnt; ++i)
504 timers [i]->at += diff;
505 }
516 506
517 now = ev_now; 507 now = ev_now;
518 } 508 }
519} 509}
520 510
521int ev_loop_done; 511int ev_loop_done;
522 512
523void ev_loop (int flags) 513void ev_loop (int flags)
524{ 514{
525 double block; 515 double block;
526 ev_loop_done = flags & EVLOOP_ONESHOT; 516 ev_loop_done = flags & EVLOOP_ONESHOT ? 1 : 0;
527 517
528 if (checkcnt) 518 if (checkcnt)
529 { 519 {
530 queue_events ((W *)checks, checkcnt, EV_CHECK); 520 queue_events ((W *)checks, checkcnt, EV_CHECK);
531 call_pending (); 521 call_pending ();
547 { 537 {
548 block = MAX_BLOCKTIME; 538 block = MAX_BLOCKTIME;
549 539
550 if (timercnt) 540 if (timercnt)
551 { 541 {
552 ev_tstamp to = timers [0]->at - get_clock () + method_fudge; 542 ev_tstamp to = timers [0]->at - (have_monotonic ? get_clock () : ev_now) + method_fudge;
553 if (block > to) block = to; 543 if (block > to) block = to;
554 } 544 }
555 545
556 if (periodiccnt) 546 if (periodiccnt)
557 { 547 {
579 queue_events ((W *)checks, checkcnt, EV_CHECK); 569 queue_events ((W *)checks, checkcnt, EV_CHECK);
580 570
581 call_pending (); 571 call_pending ();
582 } 572 }
583 while (!ev_loop_done); 573 while (!ev_loop_done);
574
575 if (ev_loop_done != 2)
576 ev_loop_done = 0;
584} 577}
585 578
586/*****************************************************************************/ 579/*****************************************************************************/
587 580
588static void 581static void
662{ 655{
663 if (ev_is_active (w)) 656 if (ev_is_active (w))
664 return; 657 return;
665 658
666 w->at += now; 659 w->at += now;
660
661 assert (("timer repeat value less than zero not allowed", w->repeat >= 0.));
667 662
668 ev_start ((W)w, ++timercnt); 663 ev_start ((W)w, ++timercnt);
669 array_needsize (timers, timermax, timercnt, ); 664 array_needsize (timers, timermax, timercnt, );
670 timers [timercnt - 1] = w; 665 timers [timercnt - 1] = w;
671 upheap ((WT *)timers, timercnt - 1); 666 upheap ((WT *)timers, timercnt - 1);
681 { 676 {
682 timers [w->active - 1] = timers [timercnt]; 677 timers [w->active - 1] = timers [timercnt];
683 downheap ((WT *)timers, timercnt, w->active - 1); 678 downheap ((WT *)timers, timercnt, w->active - 1);
684 } 679 }
685 680
681 w->at = w->repeat;
682
686 ev_stop ((W)w); 683 ev_stop ((W)w);
684}
685
686void
687evtimer_again (struct ev_timer *w)
688{
689 if (ev_is_active (w))
690 {
691 if (w->repeat)
692 {
693 w->at = now + w->repeat;
694 downheap ((WT *)timers, timercnt, w->active - 1);
695 }
696 else
697 evtimer_stop (w);
698 }
699 else if (w->repeat)
700 evtimer_start (w);
687} 701}
688 702
689void 703void
690evperiodic_start (struct ev_periodic *w) 704evperiodic_start (struct ev_periodic *w)
691{ 705{
692 if (ev_is_active (w)) 706 if (ev_is_active (w))
693 return; 707 return;
708
709 assert (("periodic interval value less than zero not allowed", w->interval >= 0.));
694 710
695 /* this formula differs from the one in periodic_reify because we do not always round up */ 711 /* this formula differs from the one in periodic_reify because we do not always round up */
696 if (w->interval) 712 if (w->interval)
697 w->at += ceil ((ev_now - w->at) / w->interval) * w->interval; 713 w->at += ceil ((ev_now - w->at) / w->interval) * w->interval;
698 714
782 ev_stop ((W)w); 798 ev_stop ((W)w);
783} 799}
784 800
785/*****************************************************************************/ 801/*****************************************************************************/
786 802
787#if 1 803#if 0
788 804
789struct ev_io wio; 805struct ev_io wio;
790 806
791static void 807static void
792sin_cb (struct ev_io *w, int revents) 808sin_cb (struct ev_io *w, int revents)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines