--- libev/ev.pod 2008/05/26 03:54:40 1.162 +++ libev/ev.pod 2008/08/06 07:01:25 1.172 @@ -4,63 +4,63 @@ =head1 SYNOPSIS - #include + #include =head2 EXAMPLE PROGRAM - // a single header file is required - #include + // a single header file is required + #include - // every watcher type has its own typedef'd struct - // with the name ev_ - ev_io stdin_watcher; - ev_timer timeout_watcher; - - // all watcher callbacks have a similar signature - // this callback is called when data is readable on stdin - static void - stdin_cb (EV_P_ struct ev_io *w, int revents) - { - puts ("stdin ready"); - // for one-shot events, one must manually stop the watcher - // with its corresponding stop function. - ev_io_stop (EV_A_ w); - - // this causes all nested ev_loop's to stop iterating - ev_unloop (EV_A_ EVUNLOOP_ALL); - } - - // another callback, this time for a time-out - static void - timeout_cb (EV_P_ struct ev_timer *w, int revents) - { - puts ("timeout"); - // this causes the innermost ev_loop to stop iterating - ev_unloop (EV_A_ EVUNLOOP_ONE); - } - - int - main (void) - { - // use the default event loop unless you have special needs - struct ev_loop *loop = ev_default_loop (0); - - // initialise an io watcher, then start it - // this one will watch for stdin to become readable - ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); - ev_io_start (loop, &stdin_watcher); - - // initialise a timer watcher, then start it - // simple non-repeating 5.5 second timeout - ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); - ev_timer_start (loop, &timeout_watcher); - - // now wait for events to arrive - ev_loop (loop, 0); - - // unloop was called, so exit - return 0; - } + // every watcher type has its own typedef'd struct + // with the name ev_ + ev_io stdin_watcher; + ev_timer timeout_watcher; + + // all watcher callbacks have a similar signature + // this callback is called when data is readable on stdin + static void + stdin_cb (EV_P_ struct ev_io *w, int revents) + { + puts ("stdin ready"); + // for one-shot events, one must manually stop the watcher + // with its corresponding stop function. + ev_io_stop (EV_A_ w); + + // this causes all nested ev_loop's to stop iterating + ev_unloop (EV_A_ EVUNLOOP_ALL); + } + + // another callback, this time for a time-out + static void + timeout_cb (EV_P_ struct ev_timer *w, int revents) + { + puts ("timeout"); + // this causes the innermost ev_loop to stop iterating + ev_unloop (EV_A_ EVUNLOOP_ONE); + } + + int + main (void) + { + // use the default event loop unless you have special needs + struct ev_loop *loop = ev_default_loop (0); + + // initialise an io watcher, then start it + // this one will watch for stdin to become readable + ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); + ev_io_start (loop, &stdin_watcher); + + // initialise a timer watcher, then start it + // simple non-repeating 5.5 second timeout + ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); + ev_timer_start (loop, &timeout_watcher); + + // now wait for events to arrive + ev_loop (loop, 0); + + // unloop was called, so exit + return 0; + } =head1 DESCRIPTION @@ -180,9 +180,9 @@ Example: Make sure we haven't accidentally been linked against the wrong version. - assert (("libev version mismatch", - ev_version_major () == EV_VERSION_MAJOR - && ev_version_minor () >= EV_VERSION_MINOR)); + assert (("libev version mismatch", + ev_version_major () == EV_VERSION_MAJOR + && ev_version_minor () >= EV_VERSION_MINOR)); =item unsigned int ev_supported_backends () @@ -194,8 +194,8 @@ Example: make sure we have the epoll method, because yeah this is cool and a must have and can we have a torrent of it please!!!11 - assert (("sorry, no epoll, no sex", - ev_supported_backends () & EVBACKEND_EPOLL)); + assert (("sorry, no epoll, no sex", + ev_supported_backends () & EVBACKEND_EPOLL)); =item unsigned int ev_recommended_backends () @@ -468,19 +468,19 @@ The most typical usage is like this: - if (!ev_default_loop (0)) - fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?"); + if (!ev_default_loop (0)) + fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?"); Restrict libev to the select and poll backends, and do not allow environment settings to be taken into account: - ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV); + ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV); Use whatever libev has to offer, but make sure that kqueue is used if available (warning, breaks stuff, best use only with your own private event loop and only if you know the OS supports your types of fds): - ev_default_loop (ev_recommended_backends () | EVBACKEND_KQUEUE); + ev_default_loop (ev_recommended_backends () | EVBACKEND_KQUEUE); =item struct ev_loop *ev_loop_new (unsigned int flags) @@ -495,9 +495,9 @@ Example: Try to create a event loop that uses epoll and nothing else. - struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV); - if (!epoller) - fatal ("no epoll found here, maybe it hides under your chair"); + struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV); + if (!epoller) + fatal ("no epoll found here, maybe it hides under your chair"); =item ev_default_destroy () @@ -606,21 +606,22 @@ - Before the first iteration, call any pending watchers. * If EVFLAG_FORKCHECK was used, check for a fork. - - If a fork was detected, queue and call all fork watchers. + - If a fork was detected (by any means), queue and call all fork watchers. - Queue and call all prepare watchers. - - If we have been forked, recreate the kernel state. + - If we have been forked, detach and recreate the kernel state + as to not disturb the other process. - Update the kernel state with all outstanding changes. - - Update the "event loop time". + - Update the "event loop time" (ev_now ()). - Calculate for how long to sleep or block, if at all (active idle watchers, EVLOOP_NONBLOCK or not having any active watchers at all will result in not sleeping). - Sleep if the I/O and timer collect interval say so. - Block the process, waiting for any events. - Queue all outstanding I/O (fd) events. - - Update the "event loop time" and do time jump handling. + - Update the "event loop time" (ev_now ()), and do time jump adjustments. - Queue all outstanding timers. - Queue all outstanding periodics. - - If no events are pending now, queue all idle watchers. + - Unless any events are pending now, queue all idle watchers. - Queue all check watchers. - Call all queued watchers in reverse order (i.e. check watchers first). Signals and child watchers are implemented as I/O watchers, and will @@ -635,7 +636,7 @@ ... queue jobs here, make sure they register event watchers as long ... as they still have work to do (even an idle watcher will do..) ev_loop (my_loop, 0); - ... jobs done. yeah! + ... jobs done or somebody called unloop. yeah! =item ev_unloop (loop, how) @@ -666,27 +667,29 @@ Example: Create a signal watcher, but keep it from keeping C running when nothing else is active. - struct ev_signal exitsig; - ev_signal_init (&exitsig, sig_cb, SIGINT); - ev_signal_start (loop, &exitsig); - evf_unref (loop); + struct ev_signal exitsig; + ev_signal_init (&exitsig, sig_cb, SIGINT); + ev_signal_start (loop, &exitsig); + evf_unref (loop); Example: For some weird reason, unregister the above signal handler again. - ev_ref (loop); - ev_signal_stop (loop, &exitsig); + ev_ref (loop); + ev_signal_stop (loop, &exitsig); =item ev_set_io_collect_interval (loop, ev_tstamp interval) =item ev_set_timeout_collect_interval (loop, ev_tstamp interval) These advanced functions influence the time that libev will spend waiting -for events. Both are by default C<0>, meaning that libev will try to -invoke timer/periodic callbacks and I/O callbacks with minimum latency. +for events. Both time intervals are by default C<0>, meaning that libev +will try to invoke timer/periodic callbacks and I/O callbacks with minimum +latency. Setting these to a higher value (the C I be >= C<0>) -allows libev to delay invocation of I/O and timer/periodic callbacks to -increase efficiency of loop iterations. +allows libev to delay invocation of I/O and timer/periodic callbacks +to increase efficiency of loop iterations (or to increase power-saving +opportunities). The background is that sometimes your program runs just fast enough to handle one (or very few) event(s) per loop iteration. While this makes @@ -712,6 +715,13 @@ usually doesn't make much sense to set it to a lower value than C<0.01>, as this approaches the timing granularity of most systems. +Setting the I can improve the opportunity for +saving power, as the program will "bundle" timer callback invocations that +are "near" in time together, by delaying some, thus reducing the number of +times the process sleeps and wakes up again. Another useful technique to +reduce iterations/wake-ups is to use C watchers and make sure +they fire on, say, one-second boundaries only. + =item ev_loop_verify (loop) This function only does something when C support has been @@ -732,18 +742,18 @@ interest in some event. For instance, if you want to wait for STDIN to become readable, you would create an C watcher for that: - static void my_cb (struct ev_loop *loop, struct ev_io *w, int revents) - { - ev_io_stop (w); - ev_unloop (loop, EVUNLOOP_ALL); - } - - struct ev_loop *loop = ev_default_loop (0); - struct ev_io stdin_watcher; - ev_init (&stdin_watcher, my_cb); - ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ); - ev_io_start (loop, &stdin_watcher); - ev_loop (loop, 0); + static void my_cb (struct ev_loop *loop, struct ev_io *w, int revents) + { + ev_io_stop (w); + ev_unloop (loop, EVUNLOOP_ALL); + } + + struct ev_loop *loop = ev_default_loop (0); + struct ev_io stdin_watcher; + ev_init (&stdin_watcher, my_cb); + ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ); + ev_io_start (loop, &stdin_watcher); + ev_loop (loop, 0); As you can see, you are responsible for allocating the memory for your watcher structures (and it is usually a bad idea to do this on the stack, @@ -980,22 +990,22 @@ member, you can also "subclass" the watcher type and provide your own data: - struct my_io - { - struct ev_io io; - int otherfd; - void *somedata; - struct whatever *mostinteresting; - } + struct my_io + { + struct ev_io io; + int otherfd; + void *somedata; + struct whatever *mostinteresting; + } And since your callback will be called with a pointer to the watcher, you can cast it back to your own type: - static void my_cb (struct ev_loop *loop, struct ev_io *w_, int revents) - { - struct my_io *w = (struct my_io *)w_; - ... - } + static void my_cb (struct ev_loop *loop, struct ev_io *w_, int revents) + { + struct my_io *w = (struct my_io *)w_; + ... + } More interesting and less C-conformant ways of casting your callback type instead have been omitted. @@ -1003,31 +1013,31 @@ Another common scenario is having some data structure with multiple watchers: - struct my_biggy - { - int some_data; - ev_timer t1; - ev_timer t2; - } + struct my_biggy + { + int some_data; + ev_timer t1; + ev_timer t2; + } In this case getting the pointer to C is a bit more complicated, you need to use C: - #include + #include + + static void + t1_cb (EV_P_ struct ev_timer *w, int revents) + { + struct my_biggy big = (struct my_biggy * + (((char *)w) - offsetof (struct my_biggy, t1)); + } - static void - t1_cb (EV_P_ struct ev_timer *w, int revents) - { - struct my_biggy big = (struct my_biggy * - (((char *)w) - offsetof (struct my_biggy, t1)); - } - - static void - t2_cb (EV_P_ struct ev_timer *w, int revents) - { - struct my_biggy big = (struct my_biggy * - (((char *)w) - offsetof (struct my_biggy, t2)); - } + static void + t2_cb (EV_P_ struct ev_timer *w, int revents) + { + struct my_biggy big = (struct my_biggy * + (((char *)w) - offsetof (struct my_biggy, t2)); + } =head1 WATCHER TYPES @@ -1164,19 +1174,19 @@ readable, but only once. Since it is likely line-buffered, you could attempt to read a whole line in the callback. - static void - stdin_readable_cb (struct ev_loop *loop, struct ev_io *w, int revents) - { - ev_io_stop (loop, w); - .. read from stdin here (or from w->fd) and haqndle any I/O errors - } - - ... - struct ev_loop *loop = ev_default_init (0); - struct ev_io stdin_readable; - ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ); - ev_io_start (loop, &stdin_readable); - ev_loop (loop, 0); + static void + stdin_readable_cb (struct ev_loop *loop, struct ev_io *w, int revents) + { + ev_io_stop (loop, w); + .. read from stdin here (or from w->fd) and haqndle any I/O errors + } + + ... + struct ev_loop *loop = ev_default_init (0); + struct ev_io stdin_readable; + ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ); + ev_io_start (loop, &stdin_readable); + ev_loop (loop, 0); =head2 C - relative and optionally repeating timeouts @@ -1271,33 +1281,33 @@ Example: Create a timer that fires after 60 seconds. - static void - one_minute_cb (struct ev_loop *loop, struct ev_timer *w, int revents) - { - .. one minute over, w is actually stopped right here - } - - struct ev_timer mytimer; - ev_timer_init (&mytimer, one_minute_cb, 60., 0.); - ev_timer_start (loop, &mytimer); + static void + one_minute_cb (struct ev_loop *loop, struct ev_timer *w, int revents) + { + .. one minute over, w is actually stopped right here + } + + struct ev_timer mytimer; + ev_timer_init (&mytimer, one_minute_cb, 60., 0.); + ev_timer_start (loop, &mytimer); Example: Create a timeout timer that times out after 10 seconds of inactivity. - static void - timeout_cb (struct ev_loop *loop, struct ev_timer *w, int revents) - { - .. ten seconds without any activity - } - - struct ev_timer mytimer; - ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */ - ev_timer_again (&mytimer); /* start timer */ - ev_loop (loop, 0); - - // and in some piece of code that gets executed on any "activity": - // reset the timeout to start ticking again at 10 seconds - ev_timer_again (&mytimer); + static void + timeout_cb (struct ev_loop *loop, struct ev_timer *w, int revents) + { + .. ten seconds without any activity + } + + struct ev_timer mytimer; + ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */ + ev_timer_again (&mytimer); /* start timer */ + ev_loop (loop, 0); + + // and in some piece of code that gets executed on any "activity": + // reset the timeout to start ticking again at 10 seconds + ev_timer_again (&mytimer); =head2 C - to cron or not to cron? @@ -1450,34 +1460,34 @@ system clock is divisible by 3600. The callback invocation times have potentially a lot of jitter, but good long-term stability. - static void - clock_cb (struct ev_loop *loop, struct ev_io *w, int revents) - { - ... its now a full hour (UTC, or TAI or whatever your clock follows) - } - - struct ev_periodic hourly_tick; - ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0); - ev_periodic_start (loop, &hourly_tick); + static void + clock_cb (struct ev_loop *loop, struct ev_io *w, int revents) + { + ... its now a full hour (UTC, or TAI or whatever your clock follows) + } + + struct ev_periodic hourly_tick; + ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0); + ev_periodic_start (loop, &hourly_tick); Example: The same as above, but use a reschedule callback to do it: - #include + #include - static ev_tstamp - my_scheduler_cb (struct ev_periodic *w, ev_tstamp now) - { - return fmod (now, 3600.) + 3600.; - } + static ev_tstamp + my_scheduler_cb (struct ev_periodic *w, ev_tstamp now) + { + return fmod (now, 3600.) + 3600.; + } - ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb); + ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb); Example: Call a callback every hour, starting now: - struct ev_periodic hourly_tick; - ev_periodic_init (&hourly_tick, clock_cb, - fmod (ev_now (loop), 3600.), 3600., 0); - ev_periodic_start (loop, &hourly_tick); + struct ev_periodic hourly_tick; + ev_periodic_init (&hourly_tick, clock_cb, + fmod (ev_now (loop), 3600.), 3600., 0); + ev_periodic_start (loop, &hourly_tick); =head2 C - signal me when a signal gets signalled! @@ -1521,15 +1531,15 @@ Example: Try to exit cleanly on SIGINT and SIGTERM. - static void - sigint_cb (struct ev_loop *loop, struct ev_signal *w, int revents) - { - ev_unloop (loop, EVUNLOOP_ALL); - } - - struct ev_signal signal_watcher; - ev_signal_init (&signal_watcher, sigint_cb, SIGINT); - ev_signal_start (loop, &sigint_cb); + static void + sigint_cb (struct ev_loop *loop, struct ev_signal *w, int revents) + { + ev_unloop (loop, EVUNLOOP_ALL); + } + + struct ev_signal signal_watcher; + ev_signal_init (&signal_watcher, sigint_cb, SIGINT); + ev_signal_start (loop, &sigint_cb); =head2 C - watch out for process status changes @@ -1599,29 +1609,29 @@ Example: C a new process and install a child handler to wait for its completion. - ev_child cw; + ev_child cw; + + static void + child_cb (EV_P_ struct ev_child *w, int revents) + { + ev_child_stop (EV_A_ w); + printf ("process %d exited with status %x\n", w->rpid, w->rstatus); + } - static void - child_cb (EV_P_ struct ev_child *w, int revents) - { - ev_child_stop (EV_A_ w); - printf ("process %d exited with status %x\n", w->rpid, w->rstatus); - } - - pid_t pid = fork (); - - if (pid < 0) - // error - else if (pid == 0) - { - // the forked child executes here - exit (1); - } - else - { - ev_child_init (&cw, child_cb, pid, 0); - ev_child_start (EV_DEFAULT_ &cw); - } + pid_t pid = fork (); + + if (pid < 0) + // error + else if (pid == 0) + { + // the forked child executes here + exit (1); + } + else + { + ev_child_init (&cw, child_cb, pid, 0); + ev_child_start (EV_DEFAULT_ &cw); + } =head2 C - did the file attributes just change? @@ -1664,13 +1674,19 @@ =head3 ABI Issues (Largefile Support) Libev by default (unless the user overrides this) uses the default -compilation environment, which means that on systems with optionally -disabled large file support, you get the 32 bit version of the stat +compilation environment, which means that on systems with large file +support disabled by default, you get the 32 bit version of the stat structure. When using the library from programs that change the ABI to use 64 bit file offsets the programs will fail. In that case you have to compile libev with the same flags to get binary compatibility. This is obviously the case with any flags that change the ABI, but the problem is -most noticeably with ev_stat and large file support. +most noticeably disabled with ev_stat and large file support. + +The solution for this is to lobby your distribution maker to make large +file interfaces available by default (as e.g. FreeBSD does) and not +optional. Libev cannot simply switch on large file support because it has +to exchange stat structures with application programs compiled using the +default compilation environment. =head3 Inotify @@ -1769,55 +1785,55 @@ Example: Watch C for attribute changes. - static void - passwd_cb (struct ev_loop *loop, ev_stat *w, int revents) - { - /* /etc/passwd changed in some way */ - if (w->attr.st_nlink) - { - printf ("passwd current size %ld\n", (long)w->attr.st_size); - printf ("passwd current atime %ld\n", (long)w->attr.st_mtime); - printf ("passwd current mtime %ld\n", (long)w->attr.st_mtime); - } - else - /* you shalt not abuse printf for puts */ - puts ("wow, /etc/passwd is not there, expect problems. " - "if this is windows, they already arrived\n"); - } + static void + passwd_cb (struct ev_loop *loop, ev_stat *w, int revents) + { + /* /etc/passwd changed in some way */ + if (w->attr.st_nlink) + { + printf ("passwd current size %ld\n", (long)w->attr.st_size); + printf ("passwd current atime %ld\n", (long)w->attr.st_mtime); + printf ("passwd current mtime %ld\n", (long)w->attr.st_mtime); + } + else + /* you shalt not abuse printf for puts */ + puts ("wow, /etc/passwd is not there, expect problems. " + "if this is windows, they already arrived\n"); + } - ... - ev_stat passwd; + ... + ev_stat passwd; - ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.); - ev_stat_start (loop, &passwd); + ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.); + ev_stat_start (loop, &passwd); Example: Like above, but additionally use a one-second delay so we do not miss updates (however, frequent updates will delay processing, too, so one might do the work both on C callback invocation I on C callback invocation). - static ev_stat passwd; - static ev_timer timer; + static ev_stat passwd; + static ev_timer timer; + + static void + timer_cb (EV_P_ ev_timer *w, int revents) + { + ev_timer_stop (EV_A_ w); + + /* now it's one second after the most recent passwd change */ + } - static void - timer_cb (EV_P_ ev_timer *w, int revents) - { - ev_timer_stop (EV_A_ w); - - /* now it's one second after the most recent passwd change */ - } - - static void - stat_cb (EV_P_ ev_stat *w, int revents) - { - /* reset the one-second timer */ - ev_timer_again (EV_A_ &timer); - } - - ... - ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.); - ev_stat_start (loop, &passwd); - ev_timer_init (&timer, timer_cb, 0., 1.02); + static void + stat_cb (EV_P_ ev_stat *w, int revents) + { + /* reset the one-second timer */ + ev_timer_again (EV_A_ &timer); + } + + ... + ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.); + ev_stat_start (loop, &passwd); + ev_timer_init (&timer, timer_cb, 0., 1.02); =head2 C - when you've got nothing better to do... @@ -1858,17 +1874,17 @@ Example: Dynamically allocate an C watcher, start it, and in the callback, free it. Also, use no error checking, as usual. - static void - idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents) - { - free (w); - // now do something you wanted to do when the program has - // no longer anything immediate to do. - } - - struct ev_idle *idle_watcher = malloc (sizeof (struct ev_idle)); - ev_idle_init (idle_watcher, idle_cb); - ev_idle_start (loop, idle_cb); + static void + idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents) + { + free (w); + // now do something you wanted to do when the program has + // no longer anything immediate to do. + } + + struct ev_idle *idle_watcher = malloc (sizeof (struct ev_idle)); + ev_idle_init (idle_watcher, idle_cb); + ev_idle_start (loop, idle_cb); =head2 C and C - customise your event loop! @@ -1950,60 +1966,60 @@ priority for the check watcher or use C explicitly, as the callbacks for the IO/timeout watchers might not have been called yet. - static ev_io iow [nfd]; - static ev_timer tw; + static ev_io iow [nfd]; + static ev_timer tw; + + static void + io_cb (ev_loop *loop, ev_io *w, int revents) + { + } + + // create io watchers for each fd and a timer before blocking + static void + adns_prepare_cb (ev_loop *loop, ev_prepare *w, int revents) + { + int timeout = 3600000; + struct pollfd fds [nfd]; + // actual code will need to loop here and realloc etc. + adns_beforepoll (ads, fds, &nfd, &timeout, timeval_from (ev_time ())); + + /* the callback is illegal, but won't be called as we stop during check */ + ev_timer_init (&tw, 0, timeout * 1e-3); + ev_timer_start (loop, &tw); + + // create one ev_io per pollfd + for (int i = 0; i < nfd; ++i) + { + ev_io_init (iow + i, io_cb, fds [i].fd, + ((fds [i].events & POLLIN ? EV_READ : 0) + | (fds [i].events & POLLOUT ? EV_WRITE : 0))); + + fds [i].revents = 0; + ev_io_start (loop, iow + i); + } + } + + // stop all watchers after blocking + static void + adns_check_cb (ev_loop *loop, ev_check *w, int revents) + { + ev_timer_stop (loop, &tw); + + for (int i = 0; i < nfd; ++i) + { + // set the relevant poll flags + // could also call adns_processreadable etc. here + struct pollfd *fd = fds + i; + int revents = ev_clear_pending (iow + i); + if (revents & EV_READ ) fd->revents |= fd->events & POLLIN; + if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT; - static void - io_cb (ev_loop *loop, ev_io *w, int revents) - { - } - - // create io watchers for each fd and a timer before blocking - static void - adns_prepare_cb (ev_loop *loop, ev_prepare *w, int revents) - { - int timeout = 3600000; - struct pollfd fds [nfd]; - // actual code will need to loop here and realloc etc. - adns_beforepoll (ads, fds, &nfd, &timeout, timeval_from (ev_time ())); - - /* the callback is illegal, but won't be called as we stop during check */ - ev_timer_init (&tw, 0, timeout * 1e-3); - ev_timer_start (loop, &tw); - - // create one ev_io per pollfd - for (int i = 0; i < nfd; ++i) - { - ev_io_init (iow + i, io_cb, fds [i].fd, - ((fds [i].events & POLLIN ? EV_READ : 0) - | (fds [i].events & POLLOUT ? EV_WRITE : 0))); - - fds [i].revents = 0; - ev_io_start (loop, iow + i); - } - } - - // stop all watchers after blocking - static void - adns_check_cb (ev_loop *loop, ev_check *w, int revents) - { - ev_timer_stop (loop, &tw); - - for (int i = 0; i < nfd; ++i) - { - // set the relevant poll flags - // could also call adns_processreadable etc. here - struct pollfd *fd = fds + i; - int revents = ev_clear_pending (iow + i); - if (revents & EV_READ ) fd->revents |= fd->events & POLLIN; - if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT; - - // now stop the watcher - ev_io_stop (loop, iow + i); - } + // now stop the watcher + ev_io_stop (loop, iow + i); + } - adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop)); - } + adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop)); + } Method 2: This would be just like method 1, but you run C in the prepare watcher and would dispose of the check watcher. @@ -2012,26 +2028,26 @@ notification (libadns does), you can also make use of the actual watcher callbacks, and only destroy/create the watchers in the prepare watcher. - static void - timer_cb (EV_P_ ev_timer *w, int revents) - { - adns_state ads = (adns_state)w->data; - update_now (EV_A); - - adns_processtimeouts (ads, &tv_now); - } - - static void - io_cb (EV_P_ ev_io *w, int revents) - { - adns_state ads = (adns_state)w->data; - update_now (EV_A); - - if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now); - if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now); - } + static void + timer_cb (EV_P_ ev_timer *w, int revents) + { + adns_state ads = (adns_state)w->data; + update_now (EV_A); - // do not ever call adns_afterpoll + adns_processtimeouts (ads, &tv_now); + } + + static void + io_cb (EV_P_ ev_io *w, int revents) + { + adns_state ads = (adns_state)w->data; + update_now (EV_A); + + if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now); + if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now); + } + + // do not ever call adns_afterpoll Method 4: Do not use a prepare or check watcher because the module you want to embed is too inflexible to support it. Instead, you can override @@ -2039,30 +2055,30 @@ loop is now no longer controllable by EV. The C module does this. - static gint - event_poll_func (GPollFD *fds, guint nfds, gint timeout) - { - int got_events = 0; - - for (n = 0; n < nfds; ++n) - // create/start io watcher that sets the relevant bits in fds[n] and increment got_events - - if (timeout >= 0) - // create/start timer - - // poll - ev_loop (EV_A_ 0); - - // stop timer again - if (timeout >= 0) - ev_timer_stop (EV_A_ &to); - - // stop io watchers again - their callbacks should have set - for (n = 0; n < nfds; ++n) - ev_io_stop (EV_A_ iow [n]); + static gint + event_poll_func (GPollFD *fds, guint nfds, gint timeout) + { + int got_events = 0; + + for (n = 0; n < nfds; ++n) + // create/start io watcher that sets the relevant bits in fds[n] and increment got_events + + if (timeout >= 0) + // create/start timer - return got_events; - } + // poll + ev_loop (EV_A_ 0); + + // stop timer again + if (timeout >= 0) + ev_timer_stop (EV_A_ &to); + + // stop io watchers again - their callbacks should have set + for (n = 0; n < nfds; ++n) + ev_io_stop (EV_A_ iow [n]); + + return got_events; + } =head2 C - when one backend isn't enough... @@ -2150,45 +2166,45 @@ C (which is C in the case no embeddable loop can be used). - struct ev_loop *loop_hi = ev_default_init (0); - struct ev_loop *loop_lo = 0; - struct ev_embed embed; - - // see if there is a chance of getting one that works - // (remember that a flags value of 0 means autodetection) - loop_lo = ev_embeddable_backends () & ev_recommended_backends () - ? ev_loop_new (ev_embeddable_backends () & ev_recommended_backends ()) - : 0; - - // if we got one, then embed it, otherwise default to loop_hi - if (loop_lo) - { - ev_embed_init (&embed, 0, loop_lo); - ev_embed_start (loop_hi, &embed); - } - else - loop_lo = loop_hi; + struct ev_loop *loop_hi = ev_default_init (0); + struct ev_loop *loop_lo = 0; + struct ev_embed embed; + + // see if there is a chance of getting one that works + // (remember that a flags value of 0 means autodetection) + loop_lo = ev_embeddable_backends () & ev_recommended_backends () + ? ev_loop_new (ev_embeddable_backends () & ev_recommended_backends ()) + : 0; + + // if we got one, then embed it, otherwise default to loop_hi + if (loop_lo) + { + ev_embed_init (&embed, 0, loop_lo); + ev_embed_start (loop_hi, &embed); + } + else + loop_lo = loop_hi; Example: Check if kqueue is available but not recommended and create a kqueue backend for use with sockets (which usually work with any kqueue implementation). Store the kqueue/socket-only event loop in C. (One might optionally use C, too). - struct ev_loop *loop = ev_default_init (0); - struct ev_loop *loop_socket = 0; - struct ev_embed embed; - - if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE) - if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE)) - { - ev_embed_init (&embed, 0, loop_socket); - ev_embed_start (loop, &embed); - } + struct ev_loop *loop = ev_default_init (0); + struct ev_loop *loop_socket = 0; + struct ev_embed embed; + + if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE) + if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE)) + { + ev_embed_init (&embed, 0, loop_socket); + ev_embed_start (loop, &embed); + } - if (!loop_socket) - loop_socket = loop; + if (!loop_socket) + loop_socket = loop; - // now use loop_socket for all sockets, and loop for everything else + // now use loop_socket for all sockets, and loop for everything else =head2 C - the audacity to resume the event loop after a fork @@ -2387,15 +2403,15 @@ C, C, C or C) and the C value passed to C: - static void stdin_ready (int revents, void *arg) - { - if (revents & EV_TIMEOUT) - /* doh, nothing entered */; - else if (revents & EV_READ) - /* stdin might have data for us, joy! */; - } + static void stdin_ready (int revents, void *arg) + { + if (revents & EV_TIMEOUT) + /* doh, nothing entered */; + else if (revents & EV_READ) + /* stdin might have data for us, joy! */; + } - ev_once (STDIN_FILENO, EV_READ, 10., stdin_ready, 0); + ev_once (STDIN_FILENO, EV_READ, 10., stdin_ready, 0); =item ev_feed_event (ev_loop *, watcher *, int revents) @@ -2454,7 +2470,7 @@ To use it, - #include + #include This automatically includes F and puts all of its definitions (many of them macros) into the global namespace. All C++ specific things are @@ -2531,14 +2547,14 @@ Example: simple class declaration and watcher initialisation - struct myclass - { - void io_cb (ev::io &w, int revents) { } - } - - myclass obj; - ev::io iow; - iow.set (&obj); + struct myclass + { + void io_cb (ev::io &w, int revents) { } + } + + myclass obj; + ev::io iow; + iow.set (&obj); =item w->set (void *data = 0) @@ -2552,8 +2568,8 @@ Example: - static void io_cb (ev::io &w, int revents) { } - iow.set (); + static void io_cb (ev::io &w, int revents) { } + iow.set (); =item w->set (struct ev_loop *) @@ -2596,19 +2612,19 @@ Example: Define a class with an IO and idle watcher, start one of them in the constructor. - class myclass - { - ev::io io; void io_cb (ev::io &w, int revents); - ev:idle idle void idle_cb (ev::idle &w, int revents); - - myclass (int fd) - { - io .set (this); - idle.set (this); - - io.start (fd, ev::READ); - } - }; + class myclass + { + ev::io io; void io_cb (ev::io &w, int revents); + ev:idle idle void idle_cb (ev::idle &w, int revents); + + myclass (int fd) + { + io .set (this); + idle.set (this); + + io.start (fd, ev::READ); + } + }; =head1 OTHER LANGUAGE BINDINGS @@ -2628,9 +2644,18 @@ to C (C), C (C) and the C event core (C and C). -It can be found and installed via CPAN, its homepage is found at +It can be found and installed via CPAN, its homepage is at L. +=item Python + +Python bindings can be found at L. It +seems to be quite complete and well-documented. Note, however, that the +patch they require for libev is outright dangerous as it breaks the ABI +for everybody else, and therefore, should never be applied in an installed +libev (if python requires an incompatible ABI then it needs to embed +libev). + =item Ruby Tony Arcieri has written a ruby extension that offers access to a subset @@ -2641,7 +2666,7 @@ =item D Leandro Lucarella has written a D language binding (F) for libev, to -be found at L. +be found at L. =back @@ -2663,9 +2688,9 @@ loop argument"). The C form is used when this is the sole argument, C is used when other arguments are following. Example: - ev_unref (EV_A); - ev_timer_add (EV_A_ watcher); - ev_loop (EV_A_ 0); + ev_unref (EV_A); + ev_timer_add (EV_A_ watcher); + ev_loop (EV_A_ 0); It assumes the variable C of type C is in scope, which is often provided by the following macro. @@ -2676,11 +2701,11 @@ loop parameter"). The C form is used when this is the sole parameter, C is used when other parameters are following. Example: - // this is how ev_unref is being declared - static void ev_unref (EV_P); + // this is how ev_unref is being declared + static void ev_unref (EV_P); - // this is how you can declare your typical callback - static void cb (EV_P_ ev_timer *w, int revents) + // this is how you can declare your typical callback + static void cb (EV_P_ ev_timer *w, int revents) It declares a parameter C of type C, quite suitable for use with C. @@ -2706,16 +2731,16 @@ macros so it will work regardless of whether multiple loops are supported or not. - static void - check_cb (EV_P_ ev_timer *w, int revents) - { - ev_check_stop (EV_A_ w); - } - - ev_check check; - ev_check_init (&check, check_cb); - ev_check_start (EV_DEFAULT_ &check); - ev_loop (EV_DEFAULT_ 0); + static void + check_cb (EV_P_ ev_timer *w, int revents) + { + ev_check_stop (EV_A_ w); + } + + ev_check check; + ev_check_init (&check, check_cb); + ev_check_start (EV_DEFAULT_ &check); + ev_loop (EV_DEFAULT_ 0); =head1 EMBEDDING @@ -2739,8 +2764,8 @@ To include only the libev core (all the C functions), with manual configuration (no autoconf): - #define EV_STANDALONE 1 - #include "ev.c" + #define EV_STANDALONE 1 + #include "ev.c" This will automatically include F, too, and should be done in a single C source file only to provide the function implementations. To use @@ -2748,8 +2773,8 @@ done by writing a wrapper around F that you can include instead and where you can put other configuration options): - #define EV_STANDALONE 1 - #include "ev.h" + #define EV_STANDALONE 1 + #include "ev.h" Both header files and implementation files can be compiled with a C++ compiler (at least, thats a stated goal, and breakage will be treated @@ -2758,18 +2783,18 @@ You need the following files in your source tree, or in a directory in your include path (e.g. in libev/ when using -Ilibev): - ev.h - ev.c - ev_vars.h - ev_wrap.h - - ev_win32.c required on win32 platforms only - - ev_select.c only when select backend is enabled (which is enabled by default) - ev_poll.c only when poll backend is enabled (disabled by default) - ev_epoll.c only when the epoll backend is enabled (disabled by default) - ev_kqueue.c only when the kqueue backend is enabled (disabled by default) - ev_port.c only when the solaris port backend is enabled (disabled by default) + ev.h + ev.c + ev_vars.h + ev_wrap.h + + ev_win32.c required on win32 platforms only + + ev_select.c only when select backend is enabled (which is enabled by default) + ev_poll.c only when poll backend is enabled (disabled by default) + ev_epoll.c only when the epoll backend is enabled (disabled by default) + ev_kqueue.c only when the kqueue backend is enabled (disabled by default) + ev_port.c only when the solaris port backend is enabled (disabled by default) F includes the backend files directly when enabled, so you only need to compile this single file. @@ -2778,18 +2803,18 @@ To include the libevent compatibility API, also include: - #include "event.c" + #include "event.c" in the file including F, and: - #include "event.h" + #include "event.h" in the files that want to use the libevent API. This also includes F. You need the following additional files for this: - event.h - event.c + event.h + event.c =head3 AUTOCONF SUPPORT @@ -2800,7 +2825,7 @@ For this of course you need the m4 file: - libev.m4 + libev.m4 =head2 PREPROCESSOR SYMBOLS/MACROS @@ -3087,9 +3112,9 @@ For example, the perl EV module uses something like this: - #define EV_COMMON \ - SV *self; /* contains this struct */ \ - SV *cb_sv, *fh /* note no trailing ";" */ + #define EV_COMMON \ + SV *self; /* contains this struct */ \ + SV *cb_sv, *fh /* note no trailing ";" */ =item EV_CB_DECLARE (type) @@ -3110,8 +3135,8 @@ exported symbols, you can use the provided F files which list all public symbols, one per line: - Symbols.ev for libev proper - Symbols.event for the libevent emulation + Symbols.ev for libev proper + Symbols.event for the libevent emulation This can also be used to rename all public symbols to avoid clashes with multiple versions of libev linked together (which is obviously bad in @@ -3142,22 +3167,22 @@ The usage in rxvt-unicode is simpler. It has a F header file that everybody includes and which overrides some configure choices: - #define EV_MINIMAL 1 - #define EV_USE_POLL 0 - #define EV_MULTIPLICITY 0 - #define EV_PERIODIC_ENABLE 0 - #define EV_STAT_ENABLE 0 - #define EV_FORK_ENABLE 0 - #define EV_CONFIG_H - #define EV_MINPRI 0 - #define EV_MAXPRI 0 + #define EV_MINIMAL 1 + #define EV_USE_POLL 0 + #define EV_MULTIPLICITY 0 + #define EV_PERIODIC_ENABLE 0 + #define EV_STAT_ENABLE 0 + #define EV_FORK_ENABLE 0 + #define EV_CONFIG_H + #define EV_MINPRI 0 + #define EV_MAXPRI 0 - #include "ev++.h" + #include "ev++.h" And a F implementation file that contains libev proper and is compiled: - #include "ev_cpp.h" - #include "ev.c" + #include "ev_cpp.h" + #include "ev.c" =head1 THREADS AND COROUTINES @@ -3175,8 +3200,9 @@ thread ever is inside a call at any point in time, e.g. by using a mutex per loop). -If you want to know which design is best for your problem, then I cannot -help you but by giving some generic advice: +If you want to know which design (one loop, locking, or multiple loops +without or something else still) is best for your problem, then I cannot +help you. I can give some generic advice however: =over 4 @@ -3287,7 +3313,7 @@ =back -=head1 Win32 platform limitations and workarounds +=head1 WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS Win32 doesn't support any of the standards (e.g. POSIX) that libev requires, and its I/O model is fundamentally incompatible with the POSIX @@ -3319,6 +3345,21 @@ notification model, which cannot be implemented efficiently on windows (Microsoft monopoly games). +A typical way to use libev under windows is to embed it (see the embedding +section for details) and use the following F header file instead +of F: + + #define EV_STANDALONE /* keeps ev from requiring config.h */ + #define EV_SELECT_IS_WINSOCKET 1 /* configure libev for windows select */ + + #include "ev.h" + +And compile the following F file into your project (make sure +you do I compile the F or any other embedded soruce files!): + + #include "evwrap.h" + #include "ev.c" + =over 4 =item The winsocket select function @@ -3326,15 +3367,16 @@ The winsocket C