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

Comparing libev/ev.c (file contents):
Revision 1.52 by root, Sat Nov 3 22:10:39 2007 UTC vs.
Revision 1.54 by root, Sun Nov 4 00:24:16 2007 UTC

113 113
114typedef struct ev_watcher *W; 114typedef struct ev_watcher *W;
115typedef struct ev_watcher_list *WL; 115typedef struct ev_watcher_list *WL;
116typedef struct ev_watcher_time *WT; 116typedef struct ev_watcher_time *WT;
117 117
118static ev_tstamp now_floor, mn_now, diff; /* monotonic clock */ 118static int have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
119static ev_tstamp rt_now;
120static int method;
121 119
122static int have_monotonic; /* runtime */ 120/*****************************************************************************/
123 121
124static ev_tstamp method_fudge; /* stupid epoll-returns-early bug */ 122typedef struct
125static void (*method_modify)(EV_P_ int fd, int oev, int nev); 123{
126static void (*method_poll)(EV_P_ ev_tstamp timeout); 124 struct ev_watcher_list *head;
125 unsigned char events;
126 unsigned char reify;
127} ANFD;
127 128
128static int activecnt; /* number of active events */ 129typedef struct
130{
131 W w;
132 int events;
133} ANPENDING;
129 134
130#if EV_USE_SELECT 135#ifdef EV_MULTIPLICITY
131static unsigned char *vec_ri, *vec_ro, *vec_wi, *vec_wo;
132static int vec_max;
133#endif
134 136
135#if EV_USEV_POLL 137struct ev_loop
136static struct pollfd *polls; 138{
137static int pollmax, pollcnt; 139# define VAR(name,decl) decl;
138static int *pollidxs; /* maps fds into structure indices */ 140# include "ev_vars.h"
139static int pollidxmax; 141};
140#endif 142# undef VAR
143# include "ev_wrap.h"
141 144
142#if EV_USE_EPOLL 145#else
143static int epoll_fd = -1;
144 146
145static struct epoll_event *events; 147# define VAR(name,decl) static decl;
146static int eventmax; 148# include "ev_vars.h"
147#endif 149# undef VAR
148 150
149#if EV_USE_KQUEUE
150static int kqueue_fd;
151static struct kevent *kqueue_changes;
152static int kqueue_changemax, kqueue_changecnt;
153static struct kevent *kqueue_events;
154static int kqueue_eventmax;
155#endif 151#endif
156 152
157/*****************************************************************************/ 153/*****************************************************************************/
158 154
159inline ev_tstamp 155inline ev_tstamp
208 cur = newcnt; \ 204 cur = newcnt; \
209 } 205 }
210 206
211/*****************************************************************************/ 207/*****************************************************************************/
212 208
213typedef struct
214{
215 struct ev_watcher_list *head;
216 unsigned char events;
217 unsigned char reify;
218} ANFD;
219
220static ANFD *anfds;
221static int anfdmax;
222
223static void 209static void
224anfds_init (ANFD *base, int count) 210anfds_init (ANFD *base, int count)
225{ 211{
226 while (count--) 212 while (count--)
227 { 213 {
230 base->reify = 0; 216 base->reify = 0;
231 217
232 ++base; 218 ++base;
233 } 219 }
234} 220}
235
236typedef struct
237{
238 W w;
239 int events;
240} ANPENDING;
241
242static ANPENDING *pendings [NUMPRI];
243static int pendingmax [NUMPRI], pendingcnt [NUMPRI];
244 221
245static void 222static void
246event (EV_P_ W w, int events) 223event (EV_P_ W w, int events)
247{ 224{
248 if (w->pending) 225 if (w->pending)
280 event (EV_A_ (W)w, ev); 257 event (EV_A_ (W)w, ev);
281 } 258 }
282} 259}
283 260
284/*****************************************************************************/ 261/*****************************************************************************/
285
286static int *fdchanges;
287static int fdchangemax, fdchangecnt;
288 262
289static void 263static void
290fd_reify (EV_P) 264fd_reify (EV_P)
291{ 265{
292 int i; 266 int i;
366 } 340 }
367} 341}
368 342
369/*****************************************************************************/ 343/*****************************************************************************/
370 344
371static struct ev_timer **timers;
372static int timermax, timercnt;
373
374static struct ev_periodic **periodics;
375static int periodicmax, periodiccnt;
376
377static void 345static void
378upheap (WT *timers, int k) 346upheap (WT *heap, int k)
379{ 347{
380 WT w = timers [k]; 348 WT w = heap [k];
381 349
382 while (k && timers [k >> 1]->at > w->at) 350 while (k && heap [k >> 1]->at > w->at)
383 { 351 {
384 timers [k] = timers [k >> 1]; 352 heap [k] = heap [k >> 1];
385 timers [k]->active = k + 1; 353 heap [k]->active = k + 1;
386 k >>= 1; 354 k >>= 1;
387 } 355 }
388 356
389 timers [k] = w; 357 heap [k] = w;
390 timers [k]->active = k + 1; 358 heap [k]->active = k + 1;
391 359
392} 360}
393 361
394static void 362static void
395downheap (WT *timers, int N, int k) 363downheap (WT *heap, int N, int k)
396{ 364{
397 WT w = timers [k]; 365 WT w = heap [k];
398 366
399 while (k < (N >> 1)) 367 while (k < (N >> 1))
400 { 368 {
401 int j = k << 1; 369 int j = k << 1;
402 370
403 if (j + 1 < N && timers [j]->at > timers [j + 1]->at) 371 if (j + 1 < N && heap [j]->at > heap [j + 1]->at)
404 ++j; 372 ++j;
405 373
406 if (w->at <= timers [j]->at) 374 if (w->at <= heap [j]->at)
407 break; 375 break;
408 376
409 timers [k] = timers [j]; 377 heap [k] = heap [j];
410 timers [k]->active = k + 1; 378 heap [k]->active = k + 1;
411 k = j; 379 k = j;
412 } 380 }
413 381
414 timers [k] = w; 382 heap [k] = w;
415 timers [k]->active = k + 1; 383 heap [k]->active = k + 1;
416} 384}
417 385
418/*****************************************************************************/ 386/*****************************************************************************/
419 387
420typedef struct 388typedef struct
426static ANSIG *signals; 394static ANSIG *signals;
427static int signalmax; 395static int signalmax;
428 396
429static int sigpipe [2]; 397static int sigpipe [2];
430static sig_atomic_t volatile gotsig; 398static sig_atomic_t volatile gotsig;
431static struct ev_io sigev;
432 399
433static void 400static void
434signals_init (ANSIG *base, int count) 401signals_init (ANSIG *base, int count)
435{ 402{
436 while (count--) 403 while (count--)
486 fcntl (sigpipe [0], F_SETFL, O_NONBLOCK); 453 fcntl (sigpipe [0], F_SETFL, O_NONBLOCK);
487 fcntl (sigpipe [1], F_SETFL, O_NONBLOCK); 454 fcntl (sigpipe [1], F_SETFL, O_NONBLOCK);
488#endif 455#endif
489 456
490 ev_io_set (&sigev, sigpipe [0], EV_READ); 457 ev_io_set (&sigev, sigpipe [0], EV_READ);
491 ev_io_start (&sigev); 458 ev_io_start (EV_A_ &sigev);
492 ev_unref (EV_A); /* child watcher should not keep loop alive */ 459 ev_unref (EV_A); /* child watcher should not keep loop alive */
493} 460}
494 461
495/*****************************************************************************/ 462/*****************************************************************************/
496
497static struct ev_idle **idles;
498static int idlemax, idlecnt;
499
500static struct ev_prepare **prepares;
501static int preparemax, preparecnt;
502
503static struct ev_check **checks;
504static int checkmax, checkcnt;
505
506/*****************************************************************************/
507
508static struct ev_child *childs [PID_HASHSIZE];
509static struct ev_signal childev;
510 463
511#ifndef WIN32 464#ifndef WIN32
512 465
513#ifndef WCONTINUED 466#ifndef WCONTINUED
514# define WCONTINUED 0 467# define WCONTINUED 0
589ev_method (EV_P) 542ev_method (EV_P)
590{ 543{
591 return method; 544 return method;
592} 545}
593 546
594int 547static void
595ev_init (EV_P_ int methods) 548loop_init (EV_P_ int methods)
596{ 549{
597 if (!method) 550 if (!method)
598 { 551 {
599#if EV_USE_MONOTONIC 552#if EV_USE_MONOTONIC
600 { 553 {
605#endif 558#endif
606 559
607 rt_now = ev_time (); 560 rt_now = ev_time ();
608 mn_now = get_clock (); 561 mn_now = get_clock ();
609 now_floor = mn_now; 562 now_floor = mn_now;
610 diff = rt_now - mn_now; 563 rtmn_diff = rt_now - mn_now;
611 564
612 if (pipe (sigpipe)) 565 if (pipe (sigpipe))
613 return 0; 566 return 0;
614 567
615 if (methods == EVMETHOD_AUTO) 568 if (methods == EVMETHOD_AUTO)
648 } 601 }
649 602
650 return method; 603 return method;
651} 604}
652 605
606#ifdef EV_MULTIPLICITY
607
608struct ev_loop *
609ev_loop_new (int methods)
610{
611 struct ev_loop *loop = (struct ev_loop *)calloc (1, sizeof (struct ev_loop));
612
613 loop_init (EV_A_ methods);
614
615 return loop;
616}
617
618void
619ev_loop_delete (EV_P)
620{
621 /*TODO*/
622 free (loop);
623}
624
625#else
626
627int
628ev_init (int methods)
629{
630 loop_init ();
631}
632
633#endif
634
653/*****************************************************************************/ 635/*****************************************************************************/
654 636
655void 637void
656ev_fork_prepare (void) 638ev_fork_prepare (void)
657{ 639{
665} 647}
666 648
667void 649void
668ev_fork_child (void) 650ev_fork_child (void)
669{ 651{
652 /*TODO*/
653#if !EV_MULTIPLICITY
670#if EV_USE_EPOLL 654#if EV_USE_EPOLL
671 if (method == EVMETHOD_EPOLL) 655 if (method == EVMETHOD_EPOLL)
672 epoll_postfork_child (); 656 epoll_postfork_child (EV_A);
673#endif 657#endif
674 658
675 ev_io_stop (&sigev); 659 ev_io_stop (EV_A_ &sigev);
676 close (sigpipe [0]); 660 close (sigpipe [0]);
677 close (sigpipe [1]); 661 close (sigpipe [1]);
678 pipe (sigpipe); 662 pipe (sigpipe);
679 siginit (); 663 siginit (EV_A);
664#endif
680} 665}
681 666
682/*****************************************************************************/ 667/*****************************************************************************/
683 668
684static void 669static void
714 downheap ((WT *)timers, timercnt, 0); 699 downheap ((WT *)timers, timercnt, 0);
715 } 700 }
716 else 701 else
717 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ 702 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
718 703
719 event ((W)w, EV_TIMEOUT); 704 event (EV_A_ (W)w, EV_TIMEOUT);
720 } 705 }
721} 706}
722 707
723static void 708static void
724periodics_reify (EV_P) 709periodics_reify (EV_P)
740 event (EV_A_ (W)w, EV_PERIODIC); 725 event (EV_A_ (W)w, EV_PERIODIC);
741 } 726 }
742} 727}
743 728
744static void 729static void
745periodics_reschedule (EV_P_ ev_tstamp diff) 730periodics_reschedule (EV_P)
746{ 731{
747 int i; 732 int i;
748 733
749 /* adjust periodics after time jump */ 734 /* adjust periodics after time jump */
750 for (i = 0; i < periodiccnt; ++i) 735 for (i = 0; i < periodiccnt; ++i)
771{ 756{
772 mn_now = get_clock (); 757 mn_now = get_clock ();
773 758
774 if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5)) 759 if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5))
775 { 760 {
776 rt_now = mn_now + diff; 761 rt_now = rtmn_diff + mn_now;
777 return 0; 762 return 0;
778 } 763 }
779 else 764 else
780 { 765 {
781 now_floor = mn_now; 766 now_floor = mn_now;
792#if EV_USE_MONOTONIC 777#if EV_USE_MONOTONIC
793 if (expect_true (have_monotonic)) 778 if (expect_true (have_monotonic))
794 { 779 {
795 if (time_update_monotonic (EV_A)) 780 if (time_update_monotonic (EV_A))
796 { 781 {
797 ev_tstamp odiff = diff; 782 ev_tstamp odiff = rtmn_diff;
798 783
799 for (i = 4; --i; ) /* loop a few times, before making important decisions */ 784 for (i = 4; --i; ) /* loop a few times, before making important decisions */
800 { 785 {
801 diff = rt_now - mn_now; 786 rtmn_diff = rt_now - mn_now;
802 787
803 if (fabs (odiff - diff) < MIN_TIMEJUMP) 788 if (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP)
804 return; /* all is well */ 789 return; /* all is well */
805 790
806 rt_now = ev_time (); 791 rt_now = ev_time ();
807 mn_now = get_clock (); 792 mn_now = get_clock ();
808 now_floor = mn_now; 793 now_floor = mn_now;
809 } 794 }
810 795
811 periodics_reschedule (EV_A_ diff - odiff); 796 periodics_reschedule (EV_A);
812 /* no timer adjustment, as the monotonic clock doesn't jump */ 797 /* no timer adjustment, as the monotonic clock doesn't jump */
798 /* timers_reschedule (EV_A_ rtmn_diff - odiff) */
813 } 799 }
814 } 800 }
815 else 801 else
816#endif 802#endif
817 { 803 {
818 rt_now = ev_time (); 804 rt_now = ev_time ();
819 805
820 if (expect_false (mn_now > rt_now || mn_now < rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP)) 806 if (expect_false (mn_now > rt_now || mn_now < rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP))
821 { 807 {
822 periodics_reschedule (EV_A_ rt_now - mn_now); 808 periodics_reschedule (EV_A);
823 809
824 /* adjust timers. this is easy, as the offset is the same for all */ 810 /* adjust timers. this is easy, as the offset is the same for all */
825 for (i = 0; i < timercnt; ++i) 811 for (i = 0; i < timercnt; ++i)
826 timers [i]->at += diff; 812 timers [i]->at += rt_now - mn_now;
827 } 813 }
828 814
829 mn_now = rt_now; 815 mn_now = rt_now;
830 } 816 }
831} 817}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines