--- libev/ev.pod 2008/02/24 06:50:16 1.133 +++ libev/ev.pod 2008/03/13 13:06:16 1.136 @@ -8,49 +8,63 @@ =head2 EXAMPLE PROGRAM + // 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; - /* called when data readable on stdin */ + // 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"); */ - ev_io_stop (EV_A_ w); /* just a syntax example */ - ev_unloop (EV_A_ EVUNLOOP_ALL); /* leave all loop calls */ + 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"); */ - ev_unloop (EV_A_ EVUNLOOP_ONE); /* leave one loop call */ + 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 */ + // 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); - /* simple non-repeating 5.5 second timeout */ + // 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); - /* loop till timeout or data ready */ + // now wait for events to arrive ev_loop (loop, 0); + // unloop was called, so exit return 0; } =head1 DESCRIPTION -The newest version of this document is also available as a html-formatted +The newest version of this document is also available as an html-formatted web page you might find easier to navigate when reading it for the first time: L. @@ -86,12 +100,13 @@ =head2 CONVENTIONS -Libev is very configurable. In this manual the default configuration will -be described, which supports multiple event loops. For more info about -various configuration options please have a look at B section in -this manual. If libev was configured without support for multiple event -loops, then all functions taking an initial argument of name C -(which is always of type C) will not have this argument. +Libev is very configurable. In this manual the default (and most common) +configuration will be described, which supports multiple event loops. For +more info about various configuration options please have a look at +B section in this manual. If libev was configured without support +for multiple event loops, then all functions taking an initial argument of +name C (which is always of type C) will not have +this argument. =head2 TIME REPRESENTATION @@ -299,8 +314,8 @@ This works by calling C on every iteration of the loop, and thus this might slow down your event loop if you do a lot of loop iterations and little real work, but is usually not noticeable (on my -Linux system for example, C is actually a simple 5-insn sequence -without a syscall and thus I fast, but my Linux system also has +GNU/Linux system for example, C is actually a simple 5-insn sequence +without a syscall and thus I fast, but my GNU/Linux system also has C which is even faster). The big advantage of this flag is that you can forget about fork (and @@ -1421,6 +1436,12 @@ watcher for a signal is stopped libev will reset the signal handler to SIG_DFL (regardless of what it was set to before). +If possible and supported, libev will install its handlers with +C behaviour enabled, so syscalls should not be unduly +interrupted. If you have a problem with syscalls getting interrupted by +signals you can block all signals in an C watcher and unblock +them in an C watcher. + =head3 Watcher-Specific Functions and Data Members =over 4 @@ -1456,7 +1477,32 @@ =head2 C - watch out for process status changes Child watchers trigger when your process receives a SIGCHLD in response to -some child status changes (most typically when a child of yours dies). +some child status changes (most typically when a child of yours dies). It +is permissible to install a child watcher I the child has been +forked (which implies it might have already exited), as long as the event +loop isn't entered (or is continued from a watcher). + +Only the default event loop is capable of handling signals, and therefore +you can only rgeister child watchers in the default event loop. + +=head3 Process Interaction + +Libev grabs C as soon as the default event loop is +initialised. This is necessary to guarantee proper behaviour even if +the first child watcher is started after the child exits. The occurance +of C is recorded asynchronously, but child reaping is done +synchronously as part of the event loop processing. Libev always reaps all +children, even ones not watched. + +=head3 Overriding the Built-In Processing + +Libev offers no special support for overriding the built-in child +processing, but if your application collides with libev's default child +handler, you can override it easily by installing your own handler for +C after initialising the default loop, and making sure the +default loop never gets destroyed. You are encouraged, however, to use an +event-based approach to child reaping and thus use libev's support for +that, so other libev users can use C watchers freely. =head3 Watcher-Specific Functions and Data Members @@ -1490,6 +1536,35 @@ =back +=head3 Examples + +Example: C a new process and install a child handler to wait for +its completion. + + 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); + } + + 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? @@ -2436,6 +2511,41 @@ }; +=head1 OTHER LANGUAGE BINDINGS + +Libev does not offer other language bindings itself, but bindings for a +numbe rof languages exist in the form of third-party packages. If you know +any interesting language binding in addition to the ones listed here, drop +me a note. + +=over 4 + +=item Perl + +The EV module implements the full libev API and is actually used to test +libev. EV is developed together with libev. Apart from the EV core module, +there are additional modules that implement libev-compatible interfaces +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 +L. + +=item Ruby + +Tony Arcieri has written a ruby extension that offers access to a subset +of the libev API and adds filehandle abstractions, asynchronous DNS and +more on top of it. It can be found via gem servers. Its homepage is at +L. + +=item D + +Leandro Lucarella has written a D language binding (F) for libev, to +be found at L. + +=back + + =head1 MACRO MAGIC Libev can be compiled with a variety of options, the most fundamantal