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.55 by root, Sun Nov 4 00:39:24 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#if 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 547inline int
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#if 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 if (loop_init (EV_A_ methods))
614 return loop;
615
616 ev_loop_delete (loop);
617
618 return 0;
619}
620
621void
622ev_loop_delete (EV_P)
623{
624 /*TODO*/
625 free (loop);
626}
627
628#else
629
630int
631ev_init (int methods)
632{
633 return loop_init (methods);
634}
635
636#endif
637
653/*****************************************************************************/ 638/*****************************************************************************/
654 639
655void 640void
656ev_fork_prepare (void) 641ev_fork_prepare (void)
657{ 642{
665} 650}
666 651
667void 652void
668ev_fork_child (void) 653ev_fork_child (void)
669{ 654{
655 /*TODO*/
656#if !EV_MULTIPLICITY
670#if EV_USE_EPOLL 657#if EV_USE_EPOLL
671 if (method == EVMETHOD_EPOLL) 658 if (method == EVMETHOD_EPOLL)
672 epoll_postfork_child (); 659 epoll_postfork_child (EV_A);
673#endif 660#endif
674 661
675 ev_io_stop (&sigev); 662 ev_io_stop (EV_A_ &sigev);
676 close (sigpipe [0]); 663 close (sigpipe [0]);
677 close (sigpipe [1]); 664 close (sigpipe [1]);
678 pipe (sigpipe); 665 pipe (sigpipe);
679 siginit (); 666 siginit (EV_A);
667#endif
680} 668}
681 669
682/*****************************************************************************/ 670/*****************************************************************************/
683 671
684static void 672static void
714 downheap ((WT *)timers, timercnt, 0); 702 downheap ((WT *)timers, timercnt, 0);
715 } 703 }
716 else 704 else
717 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ 705 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
718 706
719 event ((W)w, EV_TIMEOUT); 707 event (EV_A_ (W)w, EV_TIMEOUT);
720 } 708 }
721} 709}
722 710
723static void 711static void
724periodics_reify (EV_P) 712periodics_reify (EV_P)
740 event (EV_A_ (W)w, EV_PERIODIC); 728 event (EV_A_ (W)w, EV_PERIODIC);
741 } 729 }
742} 730}
743 731
744static void 732static void
745periodics_reschedule (EV_P_ ev_tstamp diff) 733periodics_reschedule (EV_P)
746{ 734{
747 int i; 735 int i;
748 736
749 /* adjust periodics after time jump */ 737 /* adjust periodics after time jump */
750 for (i = 0; i < periodiccnt; ++i) 738 for (i = 0; i < periodiccnt; ++i)
771{ 759{
772 mn_now = get_clock (); 760 mn_now = get_clock ();
773 761
774 if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5)) 762 if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5))
775 { 763 {
776 rt_now = mn_now + diff; 764 rt_now = rtmn_diff + mn_now;
777 return 0; 765 return 0;
778 } 766 }
779 else 767 else
780 { 768 {
781 now_floor = mn_now; 769 now_floor = mn_now;
792#if EV_USE_MONOTONIC 780#if EV_USE_MONOTONIC
793 if (expect_true (have_monotonic)) 781 if (expect_true (have_monotonic))
794 { 782 {
795 if (time_update_monotonic (EV_A)) 783 if (time_update_monotonic (EV_A))
796 { 784 {
797 ev_tstamp odiff = diff; 785 ev_tstamp odiff = rtmn_diff;
798 786
799 for (i = 4; --i; ) /* loop a few times, before making important decisions */ 787 for (i = 4; --i; ) /* loop a few times, before making important decisions */
800 { 788 {
801 diff = rt_now - mn_now; 789 rtmn_diff = rt_now - mn_now;
802 790
803 if (fabs (odiff - diff) < MIN_TIMEJUMP) 791 if (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP)
804 return; /* all is well */ 792 return; /* all is well */
805 793
806 rt_now = ev_time (); 794 rt_now = ev_time ();
807 mn_now = get_clock (); 795 mn_now = get_clock ();
808 now_floor = mn_now; 796 now_floor = mn_now;
809 } 797 }
810 798
811 periodics_reschedule (EV_A_ diff - odiff); 799 periodics_reschedule (EV_A);
812 /* no timer adjustment, as the monotonic clock doesn't jump */ 800 /* no timer adjustment, as the monotonic clock doesn't jump */
801 /* timers_reschedule (EV_A_ rtmn_diff - odiff) */
813 } 802 }
814 } 803 }
815 else 804 else
816#endif 805#endif
817 { 806 {
818 rt_now = ev_time (); 807 rt_now = ev_time ();
819 808
820 if (expect_false (mn_now > rt_now || mn_now < rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP)) 809 if (expect_false (mn_now > rt_now || mn_now < rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP))
821 { 810 {
822 periodics_reschedule (EV_A_ rt_now - mn_now); 811 periodics_reschedule (EV_A);
823 812
824 /* adjust timers. this is easy, as the offset is the same for all */ 813 /* adjust timers. this is easy, as the offset is the same for all */
825 for (i = 0; i < timercnt; ++i) 814 for (i = 0; i < timercnt; ++i)
826 timers [i]->at += diff; 815 timers [i]->at += rt_now - mn_now;
827 } 816 }
828 817
829 mn_now = rt_now; 818 mn_now = rt_now;
830 } 819 }
831} 820}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines