From 86f453cc8a0bdf9ab1bd3e4b1cd448070bddb9ac Mon Sep 17 00:00:00 2001 From: root Date: Tue, 5 Jul 2011 16:57:41 +0000 Subject: *** empty log message *** --- eio.c | 2 +- eio.pod | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/eio.c b/eio.c index cd1fb0f..2d97d91 100644 --- a/eio.c +++ b/eio.c @@ -741,7 +741,7 @@ eio_finish (eio_req *req) res2 = grp_dec (grp); - if (!res && res2) + if (!res) res = res2; } diff --git a/eio.pod b/eio.pod index 7aa8b84..3cffbe8 100644 --- a/eio.pod +++ b/eio.pod @@ -126,11 +126,55 @@ returns C<-1>. For libev, you would typically use an C watcher: the C callback would invoke C to wake up the event loop. Inside the callback set for the watcher, one would call C (followed by C again if C indicates that not -all requests have been handled yet). The race is taken care of because -libev resets/rearms the async watcher before calling your callback, -and therefore, before calling C. This might result in (some) -spurious wake-ups, but is generally harmless. +()>. + +If C is configured to not handle all results in one go +(i.e. it returns C<-1>) then you should start an idle watcher that calls +C until it returns something C. + +A full-featured wrapper would look as follows (if C is handling +all requests, it can of course be simplified a lot by removing the idle +watcher logic): + + static struct ev_loop *loop; + static ev_idle repeat_watcher; + static ev_async ready_watcher; + + /* idle watcher callback, only used when eio_poll */ + /* didn't handle all results in one call */ + static void + repeat (EV_P_ ev_idle *w, int revents) + { + if (eio_poll () != -1) + ev_idle_stop (EV_A_ w); + } + + /* eio has some results, process them */ + static void + ready (EV_P_ ev_async *w, int revents) + { + if (eio_poll () == -1) + ev_idle_start (EV_A_ &repeat_watcher); + } + + /* wake up the event loop */ + static void + want_poll (void) + { + ev_async_send (loop, &ready_watcher) + } + + void + my_init_eio () + { + loop = EV_DEFAULT; + + ev_idle_init (&repeat_watcher, repeat); + ev_async_init (&ready_watcher, ready); + ev_async_start (loop &watcher); + + eio_init (want_poll, 0); + } For most other event loops, you would typically use a pipe - the event loop should be told to wait for read readiness on the read end. In -- cgit v1.2.3