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

Comparing libev/ev.c (file contents):
Revision 1.61 by root, Sun Nov 4 19:45:09 2007 UTC vs.
Revision 1.66 by root, Sun Nov 4 23:30:53 2007 UTC

92 92
93#ifndef EV_USE_KQUEUE 93#ifndef EV_USE_KQUEUE
94# define EV_USE_KQUEUE 0 94# define EV_USE_KQUEUE 0
95#endif 95#endif
96 96
97#ifndef EV_USE_WIN32
98# ifdef WIN32
99# define EV_USE_WIN32 1
100# else
101# define EV_USE_WIN32 0
102# endif
103#endif
104
97#ifndef EV_USE_REALTIME 105#ifndef EV_USE_REALTIME
98# define EV_USE_REALTIME 1 106# define EV_USE_REALTIME 1
99#endif 107#endif
100 108
101/**/ 109/**/
224 base = realloc (base, sizeof (*base) * (newcnt)); \ 232 base = realloc (base, sizeof (*base) * (newcnt)); \
225 init (base + cur, newcnt - cur); \ 233 init (base + cur, newcnt - cur); \
226 cur = newcnt; \ 234 cur = newcnt; \
227 } 235 }
228 236
237#define array_free(stem, idx) \
238 free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0;
239
229/*****************************************************************************/ 240/*****************************************************************************/
230 241
231static void 242static void
232anfds_init (ANFD *base, int count) 243anfds_init (ANFD *base, int count)
233{ 244{
298 for (w = (struct ev_io *)anfd->head; w; w = (struct ev_io *)((WL)w)->next) 309 for (w = (struct ev_io *)anfd->head; w; w = (struct ev_io *)((WL)w)->next)
299 events |= w->events; 310 events |= w->events;
300 311
301 anfd->reify = 0; 312 anfd->reify = 0;
302 313
303 if (anfd->events != events)
304 {
305 method_modify (EV_A_ fd, anfd->events, events); 314 method_modify (EV_A_ fd, anfd->events, events);
306 anfd->events = events; 315 anfd->events = events;
307 }
308 } 316 }
309 317
310 fdchangecnt = 0; 318 fdchangecnt = 0;
311} 319}
312 320
349 357
350/* called on ENOMEM in select/poll to kill some fds and retry */ 358/* called on ENOMEM in select/poll to kill some fds and retry */
351static void 359static void
352fd_enomem (EV_P) 360fd_enomem (EV_P)
353{ 361{
354 int fd = anfdmax; 362 int fd;
355 363
356 while (fd--) 364 for (fd = anfdmax; fd--; )
357 if (anfds [fd].events) 365 if (anfds [fd].events)
358 { 366 {
359 close (fd); 367 close (fd);
360 fd_kill (EV_A_ fd); 368 fd_kill (EV_A_ fd);
361 return; 369 return;
385 WT w = heap [k]; 393 WT w = heap [k];
386 394
387 while (k && heap [k >> 1]->at > w->at) 395 while (k && heap [k >> 1]->at > w->at)
388 { 396 {
389 heap [k] = heap [k >> 1]; 397 heap [k] = heap [k >> 1];
390 heap [k]->active = k + 1; 398 ((W)heap [k])->active = k + 1;
391 k >>= 1; 399 k >>= 1;
392 } 400 }
393 401
394 heap [k] = w; 402 heap [k] = w;
395 heap [k]->active = k + 1; 403 ((W)heap [k])->active = k + 1;
396 404
397} 405}
398 406
399static void 407static void
400downheap (WT *heap, int N, int k) 408downheap (WT *heap, int N, int k)
410 418
411 if (w->at <= heap [j]->at) 419 if (w->at <= heap [j]->at)
412 break; 420 break;
413 421
414 heap [k] = heap [j]; 422 heap [k] = heap [j];
415 heap [k]->active = k + 1; 423 ((W)heap [k])->active = k + 1;
416 k = j; 424 k = j;
417 } 425 }
418 426
419 heap [k] = w; 427 heap [k] = w;
420 heap [k]->active = k + 1; 428 ((W)heap [k])->active = k + 1;
421} 429}
422 430
423/*****************************************************************************/ 431/*****************************************************************************/
424 432
425typedef struct 433typedef struct
514 struct ev_child *w; 522 struct ev_child *w;
515 523
516 for (w = (struct ev_child *)childs [chain & (PID_HASHSIZE - 1)]; w; w = (struct ev_child *)((WL)w)->next) 524 for (w = (struct ev_child *)childs [chain & (PID_HASHSIZE - 1)]; w; w = (struct ev_child *)((WL)w)->next)
517 if (w->pid == pid || !w->pid) 525 if (w->pid == pid || !w->pid)
518 { 526 {
519 w->priority = sw->priority; /* need to do it *now* */ 527 ev_priority (w) = ev_priority (sw); /* need to do it *now* */
520 w->rpid = pid; 528 w->rpid = pid;
521 w->rstatus = status; 529 w->rstatus = status;
522 event (EV_A_ (W)w, EV_CHILD); 530 event (EV_A_ (W)w, EV_CHILD);
523 } 531 }
524} 532}
525 533
526static void 534static void
608 methods = atoi (getenv ("LIBEV_METHODS")); 616 methods = atoi (getenv ("LIBEV_METHODS"));
609 else 617 else
610 methods = EVMETHOD_ANY; 618 methods = EVMETHOD_ANY;
611 619
612 method = 0; 620 method = 0;
621#if EV_USE_WIN32
622 if (!method && (methods & EVMETHOD_WIN32 )) method = win32_init (EV_A_ methods);
623#endif
613#if EV_USE_KQUEUE 624#if EV_USE_KQUEUE
614 if (!method && (methods & EVMETHOD_KQUEUE)) method = kqueue_init (EV_A_ methods); 625 if (!method && (methods & EVMETHOD_KQUEUE)) method = kqueue_init (EV_A_ methods);
615#endif 626#endif
616#if EV_USE_EPOLL 627#if EV_USE_EPOLL
617 if (!method && (methods & EVMETHOD_EPOLL )) method = epoll_init (EV_A_ methods); 628 if (!method && (methods & EVMETHOD_EPOLL )) method = epoll_init (EV_A_ methods);
626} 637}
627 638
628void 639void
629loop_destroy (EV_P) 640loop_destroy (EV_P)
630{ 641{
642 int i;
643
644#if EV_USE_WIN32
645 if (method == EVMETHOD_WIN32 ) win32_destroy (EV_A);
646#endif
631#if EV_USE_KQUEUE 647#if EV_USE_KQUEUE
632 if (method == EVMETHOD_KQUEUE) kqueue_destroy (EV_A); 648 if (method == EVMETHOD_KQUEUE) kqueue_destroy (EV_A);
633#endif 649#endif
634#if EV_USE_EPOLL 650#if EV_USE_EPOLL
635 if (method == EVMETHOD_EPOLL ) epoll_destroy (EV_A); 651 if (method == EVMETHOD_EPOLL ) epoll_destroy (EV_A);
638 if (method == EVMETHOD_POLL ) poll_destroy (EV_A); 654 if (method == EVMETHOD_POLL ) poll_destroy (EV_A);
639#endif 655#endif
640#if EV_USE_SELECT 656#if EV_USE_SELECT
641 if (method == EVMETHOD_SELECT) select_destroy (EV_A); 657 if (method == EVMETHOD_SELECT) select_destroy (EV_A);
642#endif 658#endif
659
660 for (i = NUMPRI; i--; )
661 array_free (pending, [i]);
662
663 array_free (fdchange, );
664 array_free (timer, );
665 array_free (periodic, );
666 array_free (idle, );
667 array_free (prepare, );
668 array_free (check, );
643 669
644 method = 0; 670 method = 0;
645 /*TODO*/ 671 /*TODO*/
646} 672}
647 673
790} 816}
791 817
792static void 818static void
793timers_reify (EV_P) 819timers_reify (EV_P)
794{ 820{
795 while (timercnt && timers [0]->at <= mn_now) 821 while (timercnt && ((WT)timers [0])->at <= mn_now)
796 { 822 {
797 struct ev_timer *w = timers [0]; 823 struct ev_timer *w = timers [0];
798 824
799 assert (("inactive timer on timer heap detected", ev_is_active (w))); 825 assert (("inactive timer on timer heap detected", ev_is_active (w)));
800 826
801 /* first reschedule or stop timer */ 827 /* first reschedule or stop timer */
802 if (w->repeat) 828 if (w->repeat)
803 { 829 {
804 assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.)); 830 assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
805 w->at = mn_now + w->repeat; 831 ((WT)w)->at = mn_now + w->repeat;
806 downheap ((WT *)timers, timercnt, 0); 832 downheap ((WT *)timers, timercnt, 0);
807 } 833 }
808 else 834 else
809 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ 835 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
810 836
813} 839}
814 840
815static void 841static void
816periodics_reify (EV_P) 842periodics_reify (EV_P)
817{ 843{
818 while (periodiccnt && periodics [0]->at <= rt_now) 844 while (periodiccnt && ((WT)periodics [0])->at <= rt_now)
819 { 845 {
820 struct ev_periodic *w = periodics [0]; 846 struct ev_periodic *w = periodics [0];
821 847
822 assert (("inactive timer on periodic heap detected", ev_is_active (w))); 848 assert (("inactive timer on periodic heap detected", ev_is_active (w)));
823 849
824 /* first reschedule or stop timer */ 850 /* first reschedule or stop timer */
825 if (w->interval) 851 if (w->interval)
826 { 852 {
827 w->at += floor ((rt_now - w->at) / w->interval + 1.) * w->interval; 853 ((WT)w)->at += floor ((rt_now - ((WT)w)->at) / w->interval + 1.) * w->interval;
828 assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", w->at > rt_now)); 854 assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > rt_now));
829 downheap ((WT *)periodics, periodiccnt, 0); 855 downheap ((WT *)periodics, periodiccnt, 0);
830 } 856 }
831 else 857 else
832 ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */ 858 ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
833 859
845 { 871 {
846 struct ev_periodic *w = periodics [i]; 872 struct ev_periodic *w = periodics [i];
847 873
848 if (w->interval) 874 if (w->interval)
849 { 875 {
850 ev_tstamp diff = ceil ((rt_now - w->at) / w->interval) * w->interval; 876 ev_tstamp diff = ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
851 877
852 if (fabs (diff) >= 1e-4) 878 if (fabs (diff) >= 1e-4)
853 { 879 {
854 ev_periodic_stop (EV_A_ w); 880 ev_periodic_stop (EV_A_ w);
855 ev_periodic_start (EV_A_ w); 881 ev_periodic_start (EV_A_ w);
916 { 942 {
917 periodics_reschedule (EV_A); 943 periodics_reschedule (EV_A);
918 944
919 /* adjust timers. this is easy, as the offset is the same for all */ 945 /* adjust timers. this is easy, as the offset is the same for all */
920 for (i = 0; i < timercnt; ++i) 946 for (i = 0; i < timercnt; ++i)
921 timers [i]->at += rt_now - mn_now; 947 ((WT)timers [i])->at += rt_now - mn_now;
922 } 948 }
923 949
924 mn_now = rt_now; 950 mn_now = rt_now;
925 } 951 }
926} 952}
977 { 1003 {
978 block = MAX_BLOCKTIME; 1004 block = MAX_BLOCKTIME;
979 1005
980 if (timercnt) 1006 if (timercnt)
981 { 1007 {
982 ev_tstamp to = timers [0]->at - mn_now + method_fudge; 1008 ev_tstamp to = ((WT)timers [0])->at - mn_now + method_fudge;
983 if (block > to) block = to; 1009 if (block > to) block = to;
984 } 1010 }
985 1011
986 if (periodiccnt) 1012 if (periodiccnt)
987 { 1013 {
988 ev_tstamp to = periodics [0]->at - rt_now + method_fudge; 1014 ev_tstamp to = ((WT)periodics [0])->at - rt_now + method_fudge;
989 if (block > to) block = to; 1015 if (block > to) block = to;
990 } 1016 }
991 1017
992 if (block < 0.) block = 0.; 1018 if (block < 0.) block = 0.;
993 } 1019 }
1110ev_timer_start (EV_P_ struct ev_timer *w) 1136ev_timer_start (EV_P_ struct ev_timer *w)
1111{ 1137{
1112 if (ev_is_active (w)) 1138 if (ev_is_active (w))
1113 return; 1139 return;
1114 1140
1115 w->at += mn_now; 1141 ((WT)w)->at += mn_now;
1116 1142
1117 assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.)); 1143 assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
1118 1144
1119 ev_start (EV_A_ (W)w, ++timercnt); 1145 ev_start (EV_A_ (W)w, ++timercnt);
1120 array_needsize (timers, timermax, timercnt, ); 1146 array_needsize (timers, timermax, timercnt, );
1121 timers [timercnt - 1] = w; 1147 timers [timercnt - 1] = w;
1122 upheap ((WT *)timers, timercnt - 1); 1148 upheap ((WT *)timers, timercnt - 1);
1149
1150 assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));
1123} 1151}
1124 1152
1125void 1153void
1126ev_timer_stop (EV_P_ struct ev_timer *w) 1154ev_timer_stop (EV_P_ struct ev_timer *w)
1127{ 1155{
1128 ev_clear_pending (EV_A_ (W)w); 1156 ev_clear_pending (EV_A_ (W)w);
1129 if (!ev_is_active (w)) 1157 if (!ev_is_active (w))
1130 return; 1158 return;
1131 1159
1160 assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));
1161
1132 if (w->active < timercnt--) 1162 if (((W)w)->active < timercnt--)
1133 { 1163 {
1134 timers [w->active - 1] = timers [timercnt]; 1164 timers [((W)w)->active - 1] = timers [timercnt];
1135 downheap ((WT *)timers, timercnt, w->active - 1); 1165 downheap ((WT *)timers, timercnt, ((W)w)->active - 1);
1136 } 1166 }
1137 1167
1138 w->at = w->repeat; 1168 ((WT)w)->at = w->repeat;
1139 1169
1140 ev_stop (EV_A_ (W)w); 1170 ev_stop (EV_A_ (W)w);
1141} 1171}
1142 1172
1143void 1173void
1145{ 1175{
1146 if (ev_is_active (w)) 1176 if (ev_is_active (w))
1147 { 1177 {
1148 if (w->repeat) 1178 if (w->repeat)
1149 { 1179 {
1150 w->at = mn_now + w->repeat; 1180 ((WT)w)->at = mn_now + w->repeat;
1151 downheap ((WT *)timers, timercnt, w->active - 1); 1181 downheap ((WT *)timers, timercnt, ((W)w)->active - 1);
1152 } 1182 }
1153 else 1183 else
1154 ev_timer_stop (EV_A_ w); 1184 ev_timer_stop (EV_A_ w);
1155 } 1185 }
1156 else if (w->repeat) 1186 else if (w->repeat)
1165 1195
1166 assert (("ev_periodic_start called with negative interval value", w->interval >= 0.)); 1196 assert (("ev_periodic_start called with negative interval value", w->interval >= 0.));
1167 1197
1168 /* this formula differs from the one in periodic_reify because we do not always round up */ 1198 /* this formula differs from the one in periodic_reify because we do not always round up */
1169 if (w->interval) 1199 if (w->interval)
1170 w->at += ceil ((rt_now - w->at) / w->interval) * w->interval; 1200 ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
1171 1201
1172 ev_start (EV_A_ (W)w, ++periodiccnt); 1202 ev_start (EV_A_ (W)w, ++periodiccnt);
1173 array_needsize (periodics, periodicmax, periodiccnt, ); 1203 array_needsize (periodics, periodicmax, periodiccnt, );
1174 periodics [periodiccnt - 1] = w; 1204 periodics [periodiccnt - 1] = w;
1175 upheap ((WT *)periodics, periodiccnt - 1); 1205 upheap ((WT *)periodics, periodiccnt - 1);
1206
1207 assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));
1176} 1208}
1177 1209
1178void 1210void
1179ev_periodic_stop (EV_P_ struct ev_periodic *w) 1211ev_periodic_stop (EV_P_ struct ev_periodic *w)
1180{ 1212{
1181 ev_clear_pending (EV_A_ (W)w); 1213 ev_clear_pending (EV_A_ (W)w);
1182 if (!ev_is_active (w)) 1214 if (!ev_is_active (w))
1183 return; 1215 return;
1184 1216
1217 assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));
1218
1185 if (w->active < periodiccnt--) 1219 if (((W)w)->active < periodiccnt--)
1186 { 1220 {
1187 periodics [w->active - 1] = periodics [periodiccnt]; 1221 periodics [((W)w)->active - 1] = periodics [periodiccnt];
1188 downheap ((WT *)periodics, periodiccnt, w->active - 1); 1222 downheap ((WT *)periodics, periodiccnt, ((W)w)->active - 1);
1189 } 1223 }
1190 1224
1191 ev_stop (EV_A_ (W)w); 1225 ev_stop (EV_A_ (W)w);
1192} 1226}
1193 1227
1207{ 1241{
1208 ev_clear_pending (EV_A_ (W)w); 1242 ev_clear_pending (EV_A_ (W)w);
1209 if (ev_is_active (w)) 1243 if (ev_is_active (w))
1210 return; 1244 return;
1211 1245
1212 idles [w->active - 1] = idles [--idlecnt]; 1246 idles [((W)w)->active - 1] = idles [--idlecnt];
1213 ev_stop (EV_A_ (W)w); 1247 ev_stop (EV_A_ (W)w);
1214} 1248}
1215 1249
1216void 1250void
1217ev_prepare_start (EV_P_ struct ev_prepare *w) 1251ev_prepare_start (EV_P_ struct ev_prepare *w)
1229{ 1263{
1230 ev_clear_pending (EV_A_ (W)w); 1264 ev_clear_pending (EV_A_ (W)w);
1231 if (ev_is_active (w)) 1265 if (ev_is_active (w))
1232 return; 1266 return;
1233 1267
1234 prepares [w->active - 1] = prepares [--preparecnt]; 1268 prepares [((W)w)->active - 1] = prepares [--preparecnt];
1235 ev_stop (EV_A_ (W)w); 1269 ev_stop (EV_A_ (W)w);
1236} 1270}
1237 1271
1238void 1272void
1239ev_check_start (EV_P_ struct ev_check *w) 1273ev_check_start (EV_P_ struct ev_check *w)
1251{ 1285{
1252 ev_clear_pending (EV_A_ (W)w); 1286 ev_clear_pending (EV_A_ (W)w);
1253 if (ev_is_active (w)) 1287 if (ev_is_active (w))
1254 return; 1288 return;
1255 1289
1256 checks [w->active - 1] = checks [--checkcnt]; 1290 checks [((W)w)->active - 1] = checks [--checkcnt];
1257 ev_stop (EV_A_ (W)w); 1291 ev_stop (EV_A_ (W)w);
1258} 1292}
1259 1293
1260#ifndef SA_RESTART 1294#ifndef SA_RESTART
1261# define SA_RESTART 0 1295# define SA_RESTART 0
1274 1308
1275 ev_start (EV_A_ (W)w, 1); 1309 ev_start (EV_A_ (W)w, 1);
1276 array_needsize (signals, signalmax, w->signum, signals_init); 1310 array_needsize (signals, signalmax, w->signum, signals_init);
1277 wlist_add ((WL *)&signals [w->signum - 1].head, (WL)w); 1311 wlist_add ((WL *)&signals [w->signum - 1].head, (WL)w);
1278 1312
1279 if (!w->next) 1313 if (!((WL)w)->next)
1280 { 1314 {
1281 struct sigaction sa; 1315 struct sigaction sa;
1282 sa.sa_handler = sighandler; 1316 sa.sa_handler = sighandler;
1283 sigfillset (&sa.sa_mask); 1317 sigfillset (&sa.sa_mask);
1284 sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */ 1318 sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines