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.77 by root, Thu Nov 8 00:44:17 2007 UTC

897 postfork = 1; 897 postfork = 1;
898} 898}
899 899
900/*****************************************************************************/ 900/*****************************************************************************/
901 901
902static int
903any_pending (EV_P)
904{
905 int pri;
906
907 for (pri = NUMPRI; pri--; )
908 if (pendingcnt [pri])
909 return 1;
910
911 return 0;
912}
913
902static void 914static void
903call_pending (EV_P) 915call_pending (EV_P)
904{ 916{
905 int pri; 917 int pri;
906 918
948 struct ev_periodic *w = periodics [0]; 960 struct ev_periodic *w = periodics [0];
949 961
950 assert (("inactive timer on periodic heap detected", ev_is_active (w))); 962 assert (("inactive timer on periodic heap detected", ev_is_active (w)));
951 963
952 /* first reschedule or stop timer */ 964 /* first reschedule or stop timer */
965 if (w->reschedule_cb)
966 {
967 ev_tstamp at = ((WT)w)->at = w->reschedule_cb (w, rt_now + 0.0001);
968
969 assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > rt_now));
970 downheap ((WT *)periodics, periodiccnt, 0);
971 }
953 if (w->interval) 972 else if (w->interval)
954 { 973 {
955 ((WT)w)->at += floor ((rt_now - ((WT)w)->at) / w->interval + 1.) * w->interval; 974 ((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)); 975 assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > rt_now));
957 downheap ((WT *)periodics, periodiccnt, 0); 976 downheap ((WT *)periodics, periodiccnt, 0);
958 } 977 }
971 /* adjust periodics after time jump */ 990 /* adjust periodics after time jump */
972 for (i = 0; i < periodiccnt; ++i) 991 for (i = 0; i < periodiccnt; ++i)
973 { 992 {
974 struct ev_periodic *w = periodics [i]; 993 struct ev_periodic *w = periodics [i];
975 994
995 if (w->reschedule_cb)
996 ((WT)w)->at = w->reschedule_cb (w, rt_now);
976 if (w->interval) 997 else if (w->interval)
977 {
978 ev_tstamp diff = ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval; 998 ((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 } 999 }
1000
1001 /* now rebuild the heap */
1002 for (i = periodiccnt >> 1; i--; )
1003 downheap ((WT *)periodics, periodiccnt, i);
989} 1004}
990 1005
991inline int 1006inline int
992time_update_monotonic (EV_P) 1007time_update_monotonic (EV_P)
993{ 1008{
1089 /* update fd-related kernel structures */ 1104 /* update fd-related kernel structures */
1090 fd_reify (EV_A); 1105 fd_reify (EV_A);
1091 1106
1092 /* calculate blocking time */ 1107 /* calculate blocking time */
1093 1108
1094 /* we only need this for !monotonic clockor timers, but as we basically 1109 /* we only need this for !monotonic clock or timers, but as we basically
1095 always have timers, we just calculate it always */ 1110 always have timers, we just calculate it always */
1096#if EV_USE_MONOTONIC 1111#if EV_USE_MONOTONIC
1097 if (expect_true (have_monotonic)) 1112 if (expect_true (have_monotonic))
1098 time_update_monotonic (EV_A); 1113 time_update_monotonic (EV_A);
1099 else 1114 else
1132 /* queue pending timers and reschedule them */ 1147 /* queue pending timers and reschedule them */
1133 timers_reify (EV_A); /* relative timers called last */ 1148 timers_reify (EV_A); /* relative timers called last */
1134 periodics_reify (EV_A); /* absolute timers called first */ 1149 periodics_reify (EV_A); /* absolute timers called first */
1135 1150
1136 /* queue idle watchers unless io or timers are pending */ 1151 /* queue idle watchers unless io or timers are pending */
1137 if (!pendingcnt) 1152 if (idlecnt && !any_pending (EV_A))
1138 queue_events (EV_A_ (W *)idles, idlecnt, EV_IDLE); 1153 queue_events (EV_A_ (W *)idles, idlecnt, EV_IDLE);
1139 1154
1140 /* queue check watchers, to be executed first */ 1155 /* queue check watchers, to be executed first */
1141 if (checkcnt) 1156 if (checkcnt)
1142 queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK); 1157 queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK);
1297ev_periodic_start (EV_P_ struct ev_periodic *w) 1312ev_periodic_start (EV_P_ struct ev_periodic *w)
1298{ 1313{
1299 if (ev_is_active (w)) 1314 if (ev_is_active (w))
1300 return; 1315 return;
1301 1316
1317 if (w->reschedule_cb)
1318 ((WT)w)->at = w->reschedule_cb (w, rt_now);
1319 else if (w->interval)
1320 {
1302 assert (("ev_periodic_start called with negative interval value", w->interval >= 0.)); 1321 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 */ 1322 /* 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; 1323 ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
1324 }
1307 1325
1308 ev_start (EV_A_ (W)w, ++periodiccnt); 1326 ev_start (EV_A_ (W)w, ++periodiccnt);
1309 array_needsize (struct ev_periodic *, periodics, periodicmax, periodiccnt, (void)); 1327 array_needsize (struct ev_periodic *, periodics, periodicmax, periodiccnt, (void));
1310 periodics [periodiccnt - 1] = w; 1328 periodics [periodiccnt - 1] = w;
1311 upheap ((WT *)periodics, periodiccnt - 1); 1329 upheap ((WT *)periodics, periodiccnt - 1);
1327 periodics [((W)w)->active - 1] = periodics [periodiccnt]; 1345 periodics [((W)w)->active - 1] = periodics [periodiccnt];
1328 downheap ((WT *)periodics, periodiccnt, ((W)w)->active - 1); 1346 downheap ((WT *)periodics, periodiccnt, ((W)w)->active - 1);
1329 } 1347 }
1330 1348
1331 ev_stop (EV_A_ (W)w); 1349 ev_stop (EV_A_ (W)w);
1350}
1351
1352void
1353ev_periodic_again (EV_P_ struct ev_periodic *w)
1354{
1355 ev_periodic_stop (EV_A_ w);
1356 ev_periodic_start (EV_A_ w);
1332} 1357}
1333 1358
1334void 1359void
1335ev_idle_start (EV_P_ struct ev_idle *w) 1360ev_idle_start (EV_P_ struct ev_idle *w)
1336{ 1361{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines