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

Comparing libev/ev.c (file contents):
Revision 1.75 by root, Tue Nov 6 19:29:20 2007 UTC vs.
Revision 1.84 by root, Fri Nov 9 23:04:35 2007 UTC

126#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ 126#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
127#define MAX_BLOCKTIME 59.731 /* never wait longer than this time (to detect time jumps) */ 127#define MAX_BLOCKTIME 59.731 /* never wait longer than this time (to detect time jumps) */
128#define PID_HASHSIZE 16 /* size of pid hash table, must be power of two */ 128#define PID_HASHSIZE 16 /* size of pid hash table, must be power of two */
129/*#define CLEANUP_INTERVAL 300. /* how often to try to free memory and re-check fds */ 129/*#define CLEANUP_INTERVAL 300. /* how often to try to free memory and re-check fds */
130 130
131#ifdef EV_H
132# include EV_H
133#else
131#include "ev.h" 134# include "ev.h"
135#endif
132 136
133#if __GNUC__ >= 3 137#if __GNUC__ >= 3
134# define expect(expr,value) __builtin_expect ((expr),(value)) 138# define expect(expr,value) __builtin_expect ((expr),(value))
135# define inline inline 139# define inline inline
136#else 140#else
215 int events; 219 int events;
216} ANPENDING; 220} ANPENDING;
217 221
218#if EV_MULTIPLICITY 222#if EV_MULTIPLICITY
219 223
220struct ev_loop 224 struct ev_loop
221{ 225 {
222# define VAR(name,decl) decl; 226 #define VAR(name,decl) decl;
223# include "ev_vars.h" 227 #include "ev_vars.h"
224};
225# undef VAR 228 #undef VAR
229 };
226# include "ev_wrap.h" 230 #include "ev_wrap.h"
231
232 struct ev_loop default_loop_struct;
233 static struct ev_loop *default_loop;
227 234
228#else 235#else
229 236
230# define VAR(name,decl) static decl; 237 #define VAR(name,decl) static decl;
231# include "ev_vars.h" 238 #include "ev_vars.h"
232# undef VAR 239 #undef VAR
240
241 static int default_loop;
233 242
234#endif 243#endif
235 244
236/*****************************************************************************/ 245/*****************************************************************************/
237 246
316 325
317 ++base; 326 ++base;
318 } 327 }
319} 328}
320 329
321static void 330void
322event (EV_P_ W w, int events) 331ev_feed_event (EV_P_ void *w, int revents)
323{ 332{
333 W w_ = (W)w;
334
324 if (w->pending) 335 if (w_->pending)
325 { 336 {
326 pendings [ABSPRI (w)][w->pending - 1].events |= events; 337 pendings [ABSPRI (w_)][w_->pending - 1].events |= revents;
327 return; 338 return;
328 } 339 }
329 340
330 w->pending = ++pendingcnt [ABSPRI (w)]; 341 w_->pending = ++pendingcnt [ABSPRI (w_)];
331 array_needsize (ANPENDING, pendings [ABSPRI (w)], pendingmax [ABSPRI (w)], pendingcnt [ABSPRI (w)], (void)); 342 array_needsize (ANPENDING, pendings [ABSPRI (w_)], pendingmax [ABSPRI (w_)], pendingcnt [ABSPRI (w_)], (void));
332 pendings [ABSPRI (w)][w->pending - 1].w = w; 343 pendings [ABSPRI (w_)][w_->pending - 1].w = w_;
333 pendings [ABSPRI (w)][w->pending - 1].events = events; 344 pendings [ABSPRI (w_)][w_->pending - 1].events = revents;
334} 345}
335 346
336static void 347static void
337queue_events (EV_P_ W *events, int eventcnt, int type) 348queue_events (EV_P_ W *events, int eventcnt, int type)
338{ 349{
339 int i; 350 int i;
340 351
341 for (i = 0; i < eventcnt; ++i) 352 for (i = 0; i < eventcnt; ++i)
342 event (EV_A_ events [i], type); 353 ev_feed_event (EV_A_ events [i], type);
343} 354}
344 355
345static void 356inline void
346fd_event (EV_P_ int fd, int events) 357fd_event (EV_P_ int fd, int revents)
347{ 358{
348 ANFD *anfd = anfds + fd; 359 ANFD *anfd = anfds + fd;
349 struct ev_io *w; 360 struct ev_io *w;
350 361
351 for (w = (struct ev_io *)anfd->head; w; w = (struct ev_io *)((WL)w)->next) 362 for (w = (struct ev_io *)anfd->head; w; w = (struct ev_io *)((WL)w)->next)
352 { 363 {
353 int ev = w->events & events; 364 int ev = w->events & revents;
354 365
355 if (ev) 366 if (ev)
356 event (EV_A_ (W)w, ev); 367 ev_feed_event (EV_A_ (W)w, ev);
357 } 368 }
369}
370
371void
372ev_feed_fd_event (EV_P_ int fd, int revents)
373{
374 fd_event (EV_A_ fd, revents);
358} 375}
359 376
360/*****************************************************************************/ 377/*****************************************************************************/
361 378
362static void 379static void
403 struct ev_io *w; 420 struct ev_io *w;
404 421
405 while ((w = (struct ev_io *)anfds [fd].head)) 422 while ((w = (struct ev_io *)anfds [fd].head))
406 { 423 {
407 ev_io_stop (EV_A_ w); 424 ev_io_stop (EV_A_ w);
408 event (EV_A_ (W)w, EV_ERROR | EV_READ | EV_WRITE); 425 ev_feed_event (EV_A_ (W)w, EV_ERROR | EV_READ | EV_WRITE);
409 } 426 }
410} 427}
411 428
412static int 429static int
413fd_valid (int fd) 430fd_valid (int fd)
501 518
502 heap [k] = w; 519 heap [k] = w;
503 ((W)heap [k])->active = k + 1; 520 ((W)heap [k])->active = k + 1;
504} 521}
505 522
523inline void
524adjustheap (WT *heap, int N, int k, ev_tstamp at)
525{
526 ev_tstamp old_at = heap [k]->at;
527 heap [k]->at = at;
528
529 if (old_at < at)
530 downheap (heap, N, k);
531 else
532 upheap (heap, k);
533}
534
506/*****************************************************************************/ 535/*****************************************************************************/
507 536
508typedef struct 537typedef struct
509{ 538{
510 WL head; 539 WL head;
550#endif 579#endif
551 errno = old_errno; 580 errno = old_errno;
552 } 581 }
553} 582}
554 583
584void
585ev_feed_signal_event (EV_P_ int signum)
586{
587 WL w;
588
589#if EV_MULTIPLICITY
590 assert (("feeding signal events is only supported in the default loop", loop == default_loop));
591#endif
592
593 --signum;
594
595 if (signum < 0 || signum >= signalmax)
596 return;
597
598 signals [signum].gotsig = 0;
599
600 for (w = signals [signum].head; w; w = w->next)
601 ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
602}
603
555static void 604static void
556sigcb (EV_P_ struct ev_io *iow, int revents) 605sigcb (EV_P_ struct ev_io *iow, int revents)
557{ 606{
558 WL w;
559 int signum; 607 int signum;
560 608
561#ifdef WIN32 609#ifdef WIN32
562 recv (sigpipe [0], &revents, 1, MSG_DONTWAIT); 610 recv (sigpipe [0], &revents, 1, MSG_DONTWAIT);
563#else 611#else
565#endif 613#endif
566 gotsig = 0; 614 gotsig = 0;
567 615
568 for (signum = signalmax; signum--; ) 616 for (signum = signalmax; signum--; )
569 if (signals [signum].gotsig) 617 if (signals [signum].gotsig)
570 { 618 ev_feed_signal_event (EV_A_ signum + 1);
571 signals [signum].gotsig = 0;
572
573 for (w = signals [signum].head; w; w = w->next)
574 event (EV_A_ (W)w, EV_SIGNAL);
575 }
576} 619}
577 620
578static void 621static void
579siginit (EV_P) 622siginit (EV_P)
580{ 623{
613 if (w->pid == pid || !w->pid) 656 if (w->pid == pid || !w->pid)
614 { 657 {
615 ev_priority (w) = ev_priority (sw); /* need to do it *now* */ 658 ev_priority (w) = ev_priority (sw); /* need to do it *now* */
616 w->rpid = pid; 659 w->rpid = pid;
617 w->rstatus = status; 660 w->rstatus = status;
618 event (EV_A_ (W)w, EV_CHILD); 661 ev_feed_event (EV_A_ (W)w, EV_CHILD);
619 } 662 }
620} 663}
621 664
622static void 665static void
623childcb (EV_P_ struct ev_signal *sw, int revents) 666childcb (EV_P_ struct ev_signal *sw, int revents)
625 int pid, status; 668 int pid, status;
626 669
627 if (0 < (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED))) 670 if (0 < (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED)))
628 { 671 {
629 /* make sure we are called again until all childs have been reaped */ 672 /* make sure we are called again until all childs have been reaped */
630 event (EV_A_ (W)sw, EV_SIGNAL); 673 ev_feed_event (EV_A_ (W)sw, EV_SIGNAL);
631 674
632 child_reap (EV_A_ sw, pid, pid, status); 675 child_reap (EV_A_ sw, pid, pid, status);
633 child_reap (EV_A_ sw, 0, pid, status); /* this might trigger a watcher twice, but event catches that */ 676 child_reap (EV_A_ sw, 0, pid, status); /* this might trigger a watcher twice, but event catches that */
634 } 677 }
635} 678}
720#endif 763#endif
721#if EV_USE_SELECT 764#if EV_USE_SELECT
722 if (!method && (methods & EVMETHOD_SELECT)) method = select_init (EV_A_ methods); 765 if (!method && (methods & EVMETHOD_SELECT)) method = select_init (EV_A_ methods);
723#endif 766#endif
724 767
725 ev_watcher_init (&sigev, sigcb); 768 ev_init (&sigev, sigcb);
726 ev_set_priority (&sigev, EV_MAXPRI); 769 ev_set_priority (&sigev, EV_MAXPRI);
727 } 770 }
728} 771}
729 772
730void 773void
820} 863}
821 864
822#endif 865#endif
823 866
824#if EV_MULTIPLICITY 867#if EV_MULTIPLICITY
825struct ev_loop default_loop_struct;
826static struct ev_loop *default_loop;
827
828struct ev_loop * 868struct ev_loop *
829#else 869#else
830static int default_loop;
831
832int 870int
833#endif 871#endif
834ev_default_loop (int methods) 872ev_default_loop (int methods)
835{ 873{
836 if (sigpipe [0] == sigpipe [1]) 874 if (sigpipe [0] == sigpipe [1])
897 postfork = 1; 935 postfork = 1;
898} 936}
899 937
900/*****************************************************************************/ 938/*****************************************************************************/
901 939
940static int
941any_pending (EV_P)
942{
943 int pri;
944
945 for (pri = NUMPRI; pri--; )
946 if (pendingcnt [pri])
947 return 1;
948
949 return 0;
950}
951
902static void 952static void
903call_pending (EV_P) 953call_pending (EV_P)
904{ 954{
905 int pri; 955 int pri;
906 956
910 ANPENDING *p = pendings [pri] + --pendingcnt [pri]; 960 ANPENDING *p = pendings [pri] + --pendingcnt [pri];
911 961
912 if (p->w) 962 if (p->w)
913 { 963 {
914 p->w->pending = 0; 964 p->w->pending = 0;
915 p->w->cb (EV_A_ p->w, p->events); 965 EV_CB_INVOKE (p->w, p->events);
916 } 966 }
917 } 967 }
918} 968}
919 969
920static void 970static void
934 downheap ((WT *)timers, timercnt, 0); 984 downheap ((WT *)timers, timercnt, 0);
935 } 985 }
936 else 986 else
937 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ 987 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
938 988
939 event (EV_A_ (W)w, EV_TIMEOUT); 989 ev_feed_event (EV_A_ (W)w, EV_TIMEOUT);
940 } 990 }
941} 991}
942 992
943static void 993static void
944periodics_reify (EV_P) 994periodics_reify (EV_P)
948 struct ev_periodic *w = periodics [0]; 998 struct ev_periodic *w = periodics [0];
949 999
950 assert (("inactive timer on periodic heap detected", ev_is_active (w))); 1000 assert (("inactive timer on periodic heap detected", ev_is_active (w)));
951 1001
952 /* first reschedule or stop timer */ 1002 /* first reschedule or stop timer */
1003 if (w->reschedule_cb)
1004 {
1005 ev_tstamp at = ((WT)w)->at = w->reschedule_cb (w, rt_now + 0.0001);
1006
1007 assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > rt_now));
1008 downheap ((WT *)periodics, periodiccnt, 0);
1009 }
953 if (w->interval) 1010 else if (w->interval)
954 { 1011 {
955 ((WT)w)->at += floor ((rt_now - ((WT)w)->at) / w->interval + 1.) * w->interval; 1012 ((WT)w)->at += floor ((rt_now - ((WT)w)->at) / w->interval + 1.) * w->interval;
956 assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > rt_now)); 1013 assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > rt_now));
957 downheap ((WT *)periodics, periodiccnt, 0); 1014 downheap ((WT *)periodics, periodiccnt, 0);
958 } 1015 }
959 else 1016 else
960 ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */ 1017 ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
961 1018
962 event (EV_A_ (W)w, EV_PERIODIC); 1019 ev_feed_event (EV_A_ (W)w, EV_PERIODIC);
963 } 1020 }
964} 1021}
965 1022
966static void 1023static void
967periodics_reschedule (EV_P) 1024periodics_reschedule (EV_P)
971 /* adjust periodics after time jump */ 1028 /* adjust periodics after time jump */
972 for (i = 0; i < periodiccnt; ++i) 1029 for (i = 0; i < periodiccnt; ++i)
973 { 1030 {
974 struct ev_periodic *w = periodics [i]; 1031 struct ev_periodic *w = periodics [i];
975 1032
1033 if (w->reschedule_cb)
1034 ((WT)w)->at = w->reschedule_cb (w, rt_now);
976 if (w->interval) 1035 else if (w->interval)
977 {
978 ev_tstamp diff = ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval; 1036 ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
979
980 if (fabs (diff) >= 1e-4)
981 {
982 ev_periodic_stop (EV_A_ w);
983 ev_periodic_start (EV_A_ w);
984
985 i = 0; /* restart loop, inefficient, but time jumps should be rare */
986 }
987 }
988 } 1037 }
1038
1039 /* now rebuild the heap */
1040 for (i = periodiccnt >> 1; i--; )
1041 downheap ((WT *)periodics, periodiccnt, i);
989} 1042}
990 1043
991inline int 1044inline int
992time_update_monotonic (EV_P) 1045time_update_monotonic (EV_P)
993{ 1046{
1089 /* update fd-related kernel structures */ 1142 /* update fd-related kernel structures */
1090 fd_reify (EV_A); 1143 fd_reify (EV_A);
1091 1144
1092 /* calculate blocking time */ 1145 /* calculate blocking time */
1093 1146
1094 /* we only need this for !monotonic clockor timers, but as we basically 1147 /* we only need this for !monotonic clock or timers, but as we basically
1095 always have timers, we just calculate it always */ 1148 always have timers, we just calculate it always */
1096#if EV_USE_MONOTONIC 1149#if EV_USE_MONOTONIC
1097 if (expect_true (have_monotonic)) 1150 if (expect_true (have_monotonic))
1098 time_update_monotonic (EV_A); 1151 time_update_monotonic (EV_A);
1099 else 1152 else
1132 /* queue pending timers and reschedule them */ 1185 /* queue pending timers and reschedule them */
1133 timers_reify (EV_A); /* relative timers called last */ 1186 timers_reify (EV_A); /* relative timers called last */
1134 periodics_reify (EV_A); /* absolute timers called first */ 1187 periodics_reify (EV_A); /* absolute timers called first */
1135 1188
1136 /* queue idle watchers unless io or timers are pending */ 1189 /* queue idle watchers unless io or timers are pending */
1137 if (!pendingcnt) 1190 if (idlecnt && !any_pending (EV_A))
1138 queue_events (EV_A_ (W *)idles, idlecnt, EV_IDLE); 1191 queue_events (EV_A_ (W *)idles, idlecnt, EV_IDLE);
1139 1192
1140 /* queue check watchers, to be executed first */ 1193 /* queue check watchers, to be executed first */
1141 if (checkcnt) 1194 if (checkcnt)
1142 queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK); 1195 queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK);
1280ev_timer_again (EV_P_ struct ev_timer *w) 1333ev_timer_again (EV_P_ struct ev_timer *w)
1281{ 1334{
1282 if (ev_is_active (w)) 1335 if (ev_is_active (w))
1283 { 1336 {
1284 if (w->repeat) 1337 if (w->repeat)
1285 {
1286 ((WT)w)->at = mn_now + w->repeat;
1287 downheap ((WT *)timers, timercnt, ((W)w)->active - 1); 1338 adjustheap ((WT *)timers, timercnt, ((W)w)->active - 1, mn_now + w->repeat);
1288 }
1289 else 1339 else
1290 ev_timer_stop (EV_A_ w); 1340 ev_timer_stop (EV_A_ w);
1291 } 1341 }
1292 else if (w->repeat) 1342 else if (w->repeat)
1293 ev_timer_start (EV_A_ w); 1343 ev_timer_start (EV_A_ w);
1297ev_periodic_start (EV_P_ struct ev_periodic *w) 1347ev_periodic_start (EV_P_ struct ev_periodic *w)
1298{ 1348{
1299 if (ev_is_active (w)) 1349 if (ev_is_active (w))
1300 return; 1350 return;
1301 1351
1352 if (w->reschedule_cb)
1353 ((WT)w)->at = w->reschedule_cb (w, rt_now);
1354 else if (w->interval)
1355 {
1302 assert (("ev_periodic_start called with negative interval value", w->interval >= 0.)); 1356 assert (("ev_periodic_start called with negative interval value", w->interval >= 0.));
1303
1304 /* this formula differs from the one in periodic_reify because we do not always round up */ 1357 /* this formula differs from the one in periodic_reify because we do not always round up */
1305 if (w->interval)
1306 ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval; 1358 ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
1359 }
1307 1360
1308 ev_start (EV_A_ (W)w, ++periodiccnt); 1361 ev_start (EV_A_ (W)w, ++periodiccnt);
1309 array_needsize (struct ev_periodic *, periodics, periodicmax, periodiccnt, (void)); 1362 array_needsize (struct ev_periodic *, periodics, periodicmax, periodiccnt, (void));
1310 periodics [periodiccnt - 1] = w; 1363 periodics [periodiccnt - 1] = w;
1311 upheap ((WT *)periodics, periodiccnt - 1); 1364 upheap ((WT *)periodics, periodiccnt - 1);
1327 periodics [((W)w)->active - 1] = periodics [periodiccnt]; 1380 periodics [((W)w)->active - 1] = periodics [periodiccnt];
1328 downheap ((WT *)periodics, periodiccnt, ((W)w)->active - 1); 1381 downheap ((WT *)periodics, periodiccnt, ((W)w)->active - 1);
1329 } 1382 }
1330 1383
1331 ev_stop (EV_A_ (W)w); 1384 ev_stop (EV_A_ (W)w);
1385}
1386
1387void
1388ev_periodic_again (EV_P_ struct ev_periodic *w)
1389{
1390 /* TODO: use adjustheap and recalculation */
1391 ev_periodic_stop (EV_A_ w);
1392 ev_periodic_start (EV_A_ w);
1332} 1393}
1333 1394
1334void 1395void
1335ev_idle_start (EV_P_ struct ev_idle *w) 1396ev_idle_start (EV_P_ struct ev_idle *w)
1336{ 1397{
1513 else 1574 else
1514 { 1575 {
1515 once->cb = cb; 1576 once->cb = cb;
1516 once->arg = arg; 1577 once->arg = arg;
1517 1578
1518 ev_watcher_init (&once->io, once_cb_io); 1579 ev_init (&once->io, once_cb_io);
1519 if (fd >= 0) 1580 if (fd >= 0)
1520 { 1581 {
1521 ev_io_set (&once->io, fd, events); 1582 ev_io_set (&once->io, fd, events);
1522 ev_io_start (EV_A_ &once->io); 1583 ev_io_start (EV_A_ &once->io);
1523 } 1584 }
1524 1585
1525 ev_watcher_init (&once->to, once_cb_to); 1586 ev_init (&once->to, once_cb_to);
1526 if (timeout >= 0.) 1587 if (timeout >= 0.)
1527 { 1588 {
1528 ev_timer_set (&once->to, timeout, 0.); 1589 ev_timer_set (&once->to, timeout, 0.);
1529 ev_timer_start (EV_A_ &once->to); 1590 ev_timer_start (EV_A_ &once->to);
1530 } 1591 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines