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

Comparing libev/ev.c (file contents):
Revision 1.277 by root, Sun Dec 14 21:58:08 2008 UTC vs.
Revision 1.278 by root, Tue Jan 6 19:46:56 2009 UTC

1/* 1/*
2 * libev event processing core, watcher management 2 * libev event processing core, watcher management
3 * 3 *
4 * Copyright (c) 2007,2008 Marc Alexander Lehmann <libev@schmorp.de> 4 * Copyright (c) 2007,2008,2009 Marc Alexander Lehmann <libev@schmorp.de>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without modifica- 7 * Redistribution and use in source and binary forms, with or without modifica-
8 * tion, are permitted provided that the following conditions are met: 8 * tion, are permitted provided that the following conditions are met:
9 * 9 *
748 #ifdef EV_FD_TO_WIN32_HANDLE 748 #ifdef EV_FD_TO_WIN32_HANDLE
749 anfd->handle = EV_FD_TO_WIN32_HANDLE (fd); 749 anfd->handle = EV_FD_TO_WIN32_HANDLE (fd);
750 #else 750 #else
751 anfd->handle = _get_osfhandle (fd); 751 anfd->handle = _get_osfhandle (fd);
752 #endif 752 #endif
753 assert (("libev only supports socket fds in this configuration", ioctlsocket (anfd->handle, FIONREAD, &arg) == 0)); 753 assert (("libev: only socket fds supported in this configuration", ioctlsocket (anfd->handle, FIONREAD, &arg) == 0));
754 } 754 }
755#endif 755#endif
756 756
757 { 757 {
758 unsigned char o_events = anfd->events; 758 unsigned char o_events = anfd->events;
1131ev_feed_signal_event (EV_P_ int signum) 1131ev_feed_signal_event (EV_P_ int signum)
1132{ 1132{
1133 WL w; 1133 WL w;
1134 1134
1135#if EV_MULTIPLICITY 1135#if EV_MULTIPLICITY
1136 assert (("feeding signal events is only supported in the default loop", loop == ev_default_loop_ptr)); 1136 assert (("libev: feeding signal events is only supported in the default loop", loop == ev_default_loop_ptr));
1137#endif 1137#endif
1138 1138
1139 --signum; 1139 --signum;
1140 1140
1141 if (signum < 0 || signum >= signalmax) 1141 if (signum < 0 || signum >= signalmax)
1270 /* kqueue is borked on everything but netbsd apparently */ 1270 /* kqueue is borked on everything but netbsd apparently */
1271 /* it usually doesn't work correctly on anything but sockets and pipes */ 1271 /* it usually doesn't work correctly on anything but sockets and pipes */
1272 flags &= ~EVBACKEND_KQUEUE; 1272 flags &= ~EVBACKEND_KQUEUE;
1273#endif 1273#endif
1274#ifdef __APPLE__ 1274#ifdef __APPLE__
1275 // flags &= ~EVBACKEND_KQUEUE & ~EVBACKEND_POLL; for documentation 1275 /* only select works correctly on that "unix-certified" platform */
1276 flags &= ~EVBACKEND_SELECT; 1276 flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */
1277 flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */
1277#endif 1278#endif
1278 1279
1279 return flags; 1280 return flags;
1280} 1281}
1281 1282
1534 1535
1535#if EV_VERIFY 1536#if EV_VERIFY
1536static void noinline 1537static void noinline
1537verify_watcher (EV_P_ W w) 1538verify_watcher (EV_P_ W w)
1538{ 1539{
1539 assert (("watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI)); 1540 assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
1540 1541
1541 if (w->pending) 1542 if (w->pending)
1542 assert (("pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w)); 1543 assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
1543} 1544}
1544 1545
1545static void noinline 1546static void noinline
1546verify_heap (EV_P_ ANHE *heap, int N) 1547verify_heap (EV_P_ ANHE *heap, int N)
1547{ 1548{
1548 int i; 1549 int i;
1549 1550
1550 for (i = HEAP0; i < N + HEAP0; ++i) 1551 for (i = HEAP0; i < N + HEAP0; ++i)
1551 { 1552 {
1552 assert (("active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i)); 1553 assert (("libev: active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i));
1553 assert (("heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i]))); 1554 assert (("libev: heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i])));
1554 assert (("heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i])))); 1555 assert (("libev: heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i]))));
1555 1556
1556 verify_watcher (EV_A_ (W)ANHE_w (heap [i])); 1557 verify_watcher (EV_A_ (W)ANHE_w (heap [i]));
1557 } 1558 }
1558} 1559}
1559 1560
1560static void noinline 1561static void noinline
1561array_verify (EV_P_ W *ws, int cnt) 1562array_verify (EV_P_ W *ws, int cnt)
1562{ 1563{
1563 while (cnt--) 1564 while (cnt--)
1564 { 1565 {
1565 assert (("active index mismatch", ev_active (ws [cnt]) == cnt + 1)); 1566 assert (("libev: active index mismatch", ev_active (ws [cnt]) == cnt + 1));
1566 verify_watcher (EV_A_ ws [cnt]); 1567 verify_watcher (EV_A_ ws [cnt]);
1567 } 1568 }
1568} 1569}
1569#endif 1570#endif
1570 1571
1577 1578
1578 assert (activecnt >= -1); 1579 assert (activecnt >= -1);
1579 1580
1580 assert (fdchangemax >= fdchangecnt); 1581 assert (fdchangemax >= fdchangecnt);
1581 for (i = 0; i < fdchangecnt; ++i) 1582 for (i = 0; i < fdchangecnt; ++i)
1582 assert (("negative fd in fdchanges", fdchanges [i] >= 0)); 1583 assert (("libev: negative fd in fdchanges", fdchanges [i] >= 0));
1583 1584
1584 assert (anfdmax >= 0); 1585 assert (anfdmax >= 0);
1585 for (i = 0; i < anfdmax; ++i) 1586 for (i = 0; i < anfdmax; ++i)
1586 for (w = anfds [i].head; w; w = w->next) 1587 for (w = anfds [i].head; w; w = w->next)
1587 { 1588 {
1588 verify_watcher (EV_A_ (W)w); 1589 verify_watcher (EV_A_ (W)w);
1589 assert (("inactive fd watcher on anfd list", ev_active (w) == 1)); 1590 assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1));
1590 assert (("fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i)); 1591 assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
1591 } 1592 }
1592 1593
1593 assert (timermax >= timercnt); 1594 assert (timermax >= timercnt);
1594 verify_heap (EV_A_ timers, timercnt); 1595 verify_heap (EV_A_ timers, timercnt);
1595 1596
1712 { 1713 {
1713 ANPENDING *p = pendings [pri] + --pendingcnt [pri]; 1714 ANPENDING *p = pendings [pri] + --pendingcnt [pri];
1714 1715
1715 if (expect_true (p->w)) 1716 if (expect_true (p->w))
1716 { 1717 {
1717 /*assert (("non-pending watcher on pending list", p->w->pending));*/ 1718 /*assert (("libev: non-pending watcher on pending list", p->w->pending));*/
1718 1719
1719 p->w->pending = 0; 1720 p->w->pending = 0;
1720 EV_CB_INVOKE (p->w, p->events); 1721 EV_CB_INVOKE (p->w, p->events);
1721 EV_FREQUENT_CHECK; 1722 EV_FREQUENT_CHECK;
1722 } 1723 }
1753 1754
1754 while (timercnt && ANHE_at (timers [HEAP0]) < mn_now) 1755 while (timercnt && ANHE_at (timers [HEAP0]) < mn_now)
1755 { 1756 {
1756 ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]); 1757 ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]);
1757 1758
1758 /*assert (("inactive timer on timer heap detected", ev_is_active (w)));*/ 1759 /*assert (("libev: inactive timer on timer heap detected", ev_is_active (w)));*/
1759 1760
1760 /* first reschedule or stop timer */ 1761 /* first reschedule or stop timer */
1761 if (w->repeat) 1762 if (w->repeat)
1762 { 1763 {
1763 ev_at (w) += w->repeat; 1764 ev_at (w) += w->repeat;
1764 if (ev_at (w) < mn_now) 1765 if (ev_at (w) < mn_now)
1765 ev_at (w) = mn_now; 1766 ev_at (w) = mn_now;
1766 1767
1767 assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.)); 1768 assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > 0.));
1768 1769
1769 ANHE_at_cache (timers [HEAP0]); 1770 ANHE_at_cache (timers [HEAP0]);
1770 downheap (timers, timercnt, HEAP0); 1771 downheap (timers, timercnt, HEAP0);
1771 } 1772 }
1772 else 1773 else
1785 1786
1786 while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now) 1787 while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
1787 { 1788 {
1788 ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]); 1789 ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
1789 1790
1790 /*assert (("inactive timer on periodic heap detected", ev_is_active (w)));*/ 1791 /*assert (("libev: inactive timer on periodic heap detected", ev_is_active (w)));*/
1791 1792
1792 /* first reschedule or stop timer */ 1793 /* first reschedule or stop timer */
1793 if (w->reschedule_cb) 1794 if (w->reschedule_cb)
1794 { 1795 {
1795 ev_at (w) = w->reschedule_cb (w, ev_rt_now); 1796 ev_at (w) = w->reschedule_cb (w, ev_rt_now);
1796 1797
1797 assert (("ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now)); 1798 assert (("libev: ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now));
1798 1799
1799 ANHE_at_cache (periodics [HEAP0]); 1800 ANHE_at_cache (periodics [HEAP0]);
1800 downheap (periodics, periodiccnt, HEAP0); 1801 downheap (periodics, periodiccnt, HEAP0);
1801 } 1802 }
1802 else if (w->interval) 1803 else if (w->interval)
2153 int fd = w->fd; 2154 int fd = w->fd;
2154 2155
2155 if (expect_false (ev_is_active (w))) 2156 if (expect_false (ev_is_active (w)))
2156 return; 2157 return;
2157 2158
2158 assert (("ev_io_start called with negative fd", fd >= 0)); 2159 assert (("libev: ev_io_start called with negative fd", fd >= 0));
2159 assert (("ev_io start called with illegal event mask", !(w->events & ~(EV_IOFDSET | EV_READ | EV_WRITE)))); 2160 assert (("libev: ev_io start called with illegal event mask", !(w->events & ~(EV_IOFDSET | EV_READ | EV_WRITE))));
2160 2161
2161 EV_FREQUENT_CHECK; 2162 EV_FREQUENT_CHECK;
2162 2163
2163 ev_start (EV_A_ (W)w, 1); 2164 ev_start (EV_A_ (W)w, 1);
2164 array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero); 2165 array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);
2175{ 2176{
2176 clear_pending (EV_A_ (W)w); 2177 clear_pending (EV_A_ (W)w);
2177 if (expect_false (!ev_is_active (w))) 2178 if (expect_false (!ev_is_active (w)))
2178 return; 2179 return;
2179 2180
2180 assert (("ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax)); 2181 assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
2181 2182
2182 EV_FREQUENT_CHECK; 2183 EV_FREQUENT_CHECK;
2183 2184
2184 wlist_del (&anfds[w->fd].head, (WL)w); 2185 wlist_del (&anfds[w->fd].head, (WL)w);
2185 ev_stop (EV_A_ (W)w); 2186 ev_stop (EV_A_ (W)w);
2195 if (expect_false (ev_is_active (w))) 2196 if (expect_false (ev_is_active (w)))
2196 return; 2197 return;
2197 2198
2198 ev_at (w) += mn_now; 2199 ev_at (w) += mn_now;
2199 2200
2200 assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.)); 2201 assert (("libev: ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
2201 2202
2202 EV_FREQUENT_CHECK; 2203 EV_FREQUENT_CHECK;
2203 2204
2204 ++timercnt; 2205 ++timercnt;
2205 ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1); 2206 ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1);
2208 ANHE_at_cache (timers [ev_active (w)]); 2209 ANHE_at_cache (timers [ev_active (w)]);
2209 upheap (timers, ev_active (w)); 2210 upheap (timers, ev_active (w));
2210 2211
2211 EV_FREQUENT_CHECK; 2212 EV_FREQUENT_CHECK;
2212 2213
2213 /*assert (("internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/ 2214 /*assert (("libev: internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
2214} 2215}
2215 2216
2216void noinline 2217void noinline
2217ev_timer_stop (EV_P_ ev_timer *w) 2218ev_timer_stop (EV_P_ ev_timer *w)
2218{ 2219{
2223 EV_FREQUENT_CHECK; 2224 EV_FREQUENT_CHECK;
2224 2225
2225 { 2226 {
2226 int active = ev_active (w); 2227 int active = ev_active (w);
2227 2228
2228 assert (("internal timer heap corruption", ANHE_w (timers [active]) == (WT)w)); 2229 assert (("libev: internal timer heap corruption", ANHE_w (timers [active]) == (WT)w));
2229 2230
2230 --timercnt; 2231 --timercnt;
2231 2232
2232 if (expect_true (active < timercnt + HEAP0)) 2233 if (expect_true (active < timercnt + HEAP0))
2233 { 2234 {
2277 2278
2278 if (w->reschedule_cb) 2279 if (w->reschedule_cb)
2279 ev_at (w) = w->reschedule_cb (w, ev_rt_now); 2280 ev_at (w) = w->reschedule_cb (w, ev_rt_now);
2280 else if (w->interval) 2281 else if (w->interval)
2281 { 2282 {
2282 assert (("ev_periodic_start called with negative interval value", w->interval >= 0.)); 2283 assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.));
2283 /* this formula differs from the one in periodic_reify because we do not always round up */ 2284 /* this formula differs from the one in periodic_reify because we do not always round up */
2284 ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval; 2285 ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
2285 } 2286 }
2286 else 2287 else
2287 ev_at (w) = w->offset; 2288 ev_at (w) = w->offset;
2295 ANHE_at_cache (periodics [ev_active (w)]); 2296 ANHE_at_cache (periodics [ev_active (w)]);
2296 upheap (periodics, ev_active (w)); 2297 upheap (periodics, ev_active (w));
2297 2298
2298 EV_FREQUENT_CHECK; 2299 EV_FREQUENT_CHECK;
2299 2300
2300 /*assert (("internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/ 2301 /*assert (("libev: internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
2301} 2302}
2302 2303
2303void noinline 2304void noinline
2304ev_periodic_stop (EV_P_ ev_periodic *w) 2305ev_periodic_stop (EV_P_ ev_periodic *w)
2305{ 2306{
2310 EV_FREQUENT_CHECK; 2311 EV_FREQUENT_CHECK;
2311 2312
2312 { 2313 {
2313 int active = ev_active (w); 2314 int active = ev_active (w);
2314 2315
2315 assert (("internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w)); 2316 assert (("libev: internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w));
2316 2317
2317 --periodiccnt; 2318 --periodiccnt;
2318 2319
2319 if (expect_true (active < periodiccnt + HEAP0)) 2320 if (expect_true (active < periodiccnt + HEAP0))
2320 { 2321 {
2343 2344
2344void noinline 2345void noinline
2345ev_signal_start (EV_P_ ev_signal *w) 2346ev_signal_start (EV_P_ ev_signal *w)
2346{ 2347{
2347#if EV_MULTIPLICITY 2348#if EV_MULTIPLICITY
2348 assert (("signal watchers are only supported in the default loop", loop == ev_default_loop_ptr)); 2349 assert (("libev: signal watchers are only supported in the default loop", loop == ev_default_loop_ptr));
2349#endif 2350#endif
2350 if (expect_false (ev_is_active (w))) 2351 if (expect_false (ev_is_active (w)))
2351 return; 2352 return;
2352 2353
2353 assert (("ev_signal_start called with illegal signal number", w->signum > 0)); 2354 assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0));
2354 2355
2355 evpipe_init (EV_A); 2356 evpipe_init (EV_A);
2356 2357
2357 EV_FREQUENT_CHECK; 2358 EV_FREQUENT_CHECK;
2358 2359
2409 2410
2410void 2411void
2411ev_child_start (EV_P_ ev_child *w) 2412ev_child_start (EV_P_ ev_child *w)
2412{ 2413{
2413#if EV_MULTIPLICITY 2414#if EV_MULTIPLICITY
2414 assert (("child watchers are only supported in the default loop", loop == ev_default_loop_ptr)); 2415 assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
2415#endif 2416#endif
2416 if (expect_false (ev_is_active (w))) 2417 if (expect_false (ev_is_active (w)))
2417 return; 2418 return;
2418 2419
2419 EV_FREQUENT_CHECK; 2420 EV_FREQUENT_CHECK;
2933 if (expect_false (ev_is_active (w))) 2934 if (expect_false (ev_is_active (w)))
2934 return; 2935 return;
2935 2936
2936 { 2937 {
2937 struct ev_loop *loop = w->other; 2938 struct ev_loop *loop = w->other;
2938 assert (("loop to be embedded is not embeddable", backend & ev_embeddable_backends ())); 2939 assert (("libev: loop to be embedded is not embeddable", backend & ev_embeddable_backends ()));
2939 ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ); 2940 ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ);
2940 } 2941 }
2941 2942
2942 EV_FREQUENT_CHECK; 2943 EV_FREQUENT_CHECK;
2943 2944

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines