diff options
-rw-r--r-- | Changes | 6 | ||||
-rw-r--r-- | ev.3 | 22 | ||||
-rw-r--r-- | ev.c | 6 | ||||
-rw-r--r-- | ev.h | 2 | ||||
-rw-r--r-- | ev.pod | 12 | ||||
-rw-r--r-- | event.c | 33 | ||||
-rw-r--r-- | event.h | 11 |
7 files changed, 68 insertions, 24 deletions
@@ -7,7 +7,11 @@ TODO: document WSA_EV_USE_SOCKET in win32 part TODO: ^ OR use WSASend/WSARecv on the handle, which always works TODO: use __OPTIMIZE__ or __OPTIMIZE_SIZE__? -TODO: Jeff Davey libev patch + - fix event_base_loop return code, add event_get_callback, event_base_new, + event_base_get_method calls to improve libevent 1.x emulation and add + some libevent 2.x funcitonality (based on a patch by Jeff Davey). + - ev_run now returns a boolean status (true meaning watchers are + still active). - ev_once: undef EV_ERROR in ev_kqueue.c, to avoid clashing with libev's EV_ERROR (reported by 191919). - (ecb) add memory fence support for xlC (Darin McBride). @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "LIBEV 3" -.TH LIBEV 3 "2012-03-23" "libev-4.11" "libev - high performance full featured event loop" +.TH LIBEV 3 "2012-04-03" "libev-4.11" "libev - high performance full featured event loop" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -687,9 +687,9 @@ It scales in the same way as the epoll backend, but the interface to the kernel is more efficient (which says nothing about its actual speed, of course). While stopping, setting and starting an I/O watcher does never cause an extra system call as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to -two event changes per incident. Support for \f(CW\*(C`fork ()\*(C'\fR is very bad (but -sane, unlike epoll) and it drops fds silently in similarly hard-to-detect -cases +two event changes per incident. Support for \f(CW\*(C`fork ()\*(C'\fR is very bad (you +might have to leak fd's on fork, but it's more sane than epoll) and it +drops fds silently in similarly hard-to-detect cases .Sp This backend usually performs well under most conditions. .Sp @@ -911,18 +911,22 @@ without a previous call to \f(CW\*(C`ev_suspend\*(C'\fR. .Sp Calling \f(CW\*(C`ev_suspend\*(C'\fR/\f(CW\*(C`ev_resume\*(C'\fR has the side effect of updating the event loop time (see \f(CW\*(C`ev_now_update\*(C'\fR). -.IP "ev_run (loop, int flags)" 4 -.IX Item "ev_run (loop, int flags)" +.IP "bool ev_run (loop, int flags)" 4 +.IX Item "bool ev_run (loop, int flags)" Finally, this is it, the event handler. This function usually is called after you have initialised all your watchers and you want to start handling events. It will ask the operating system for any new events, call -the watcher callbacks, an then repeat the whole process indefinitely: This +the watcher callbacks, and then repeat the whole process indefinitely: This is why event loops are called \fIloops\fR. .Sp If the flags argument is specified as \f(CW0\fR, it will keep handling events until either no event watchers are active anymore or \f(CW\*(C`ev_break\*(C'\fR was called. .Sp +The return value is false if there are no more active watchers (which +usually means \*(L"all jobs done\*(R" or \*(L"deadlock\*(R"), and true in all other cases +(which usually means " you should call \f(CW\*(C`ev_run\*(C'\fR again"). +.Sp Please note that an explicit \f(CW\*(C`ev_break\*(C'\fR is usually better than relying on all watchers to be stopped when deciding when a program has finished (especially in interactive programs), but having a program @@ -930,8 +934,8 @@ that automatically loops as long as it has to and no longer by virtue of relying on its watchers stopping correctly, that is truly a thing of beauty. .Sp -This function is also \fImostly\fR exception-safe \- you can break out of -a \f(CW\*(C`ev_run\*(C'\fR call by calling \f(CW\*(C`longjmp\*(C'\fR in a callback, throwing a \*(C+ +This function is \fImostly\fR exception-safe \- you can break out of a +\&\f(CW\*(C`ev_run\*(C'\fR call by calling \f(CW\*(C`longjmp\*(C'\fR in a callback, throwing a \*(C+ exception and so on. This does not decrement the \f(CW\*(C`ev_depth\*(C'\fR value, nor will it clear any outstanding \f(CW\*(C`EVBREAK_ONE\*(C'\fR breaks. .Sp @@ -1,7 +1,7 @@ /* * libev event processing core, watcher management * - * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de> + * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- @@ -2932,7 +2932,7 @@ time_update (EV_P_ ev_tstamp max_block) } } -void +int ev_run (EV_P_ int flags) { #if EV_FEATURE_API @@ -3099,6 +3099,8 @@ ev_run (EV_P_ int flags) #if EV_FEATURE_API --loop_depth; #endif + + return activecnt; } void @@ -624,7 +624,7 @@ enum { }; #if EV_PROTOTYPES -EV_API_DECL void ev_run (EV_P_ int flags EV_CPP (= 0)); +EV_API_DECL int ev_run (EV_P_ int flags EV_CPP (= 0)); EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)); /* break out of the loop */ /* @@ -794,18 +794,22 @@ without a previous call to C<ev_suspend>. Calling C<ev_suspend>/C<ev_resume> has the side effect of updating the event loop time (see C<ev_now_update>). -=item ev_run (loop, int flags) +=item bool ev_run (loop, int flags) Finally, this is it, the event handler. This function usually is called after you have initialised all your watchers and you want to start handling events. It will ask the operating system for any new events, call -the watcher callbacks, an then repeat the whole process indefinitely: This +the watcher callbacks, and then repeat the whole process indefinitely: This is why event loops are called I<loops>. If the flags argument is specified as C<0>, it will keep handling events until either no event watchers are active anymore or C<ev_break> was called. +The return value is false if there are no more active watchers (which +usually means "all jobs done" or "deadlock"), and true in all other cases +(which usually means " you should call C<ev_run> again"). + Please note that an explicit C<ev_break> is usually better than relying on all watchers to be stopped when deciding when a program has finished (especially in interactive programs), but having a program @@ -813,8 +817,8 @@ that automatically loops as long as it has to and no longer by virtue of relying on its watchers stopping correctly, that is truly a thing of beauty. -This function is also I<mostly> exception-safe - you can break out of -a C<ev_run> call by calling C<longjmp> in a callback, throwing a C++ +This function is I<mostly> exception-safe - you can break out of a +C<ev_run> call by calling C<longjmp> in a callback, throwing a C++ exception and so on. This does not decrement the C<ev_depth> value, nor will it clear any outstanding C<EVBREAK_ONE> breaks. @@ -78,13 +78,15 @@ ev_tv_get (struct timeval *tv) #define EVENT_STRINGIFY(s) # s #define EVENT_VERSION(a,b) EVENT_STRINGIFY (a) "." EVENT_STRINGIFY (b) -const char *event_get_version (void) +const char * +event_get_version (void) { /* returns ABI, not API or library, version */ return EVENT_VERSION (EV_VERSION_MAJOR, EV_VERSION_MINOR); } -const char *event_get_method (void) +const char * +event_get_method (void) { return "libev"; } @@ -105,6 +107,23 @@ void *event_init (void) return ev_x_cur; } +const char * +event_base_get_method (const struct event_base *base) +{ + return "libev"; +} + +struct event_base * +event_base_new (void) +{ +#if EV_MULTIPLICITY + return (struct event_base *)ev_loop_new (EVFLAG_AUTO); +#else + assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY")); + return NULL; +#endif +} + void event_base_free (struct event_base *base) { dLOOPbase; @@ -137,6 +156,12 @@ int event_loopexit (struct timeval *tv) return event_base_loopexit (ev_x_cur, tv); } +event_callback_fn event_get_callback +(const struct event *ev) +{ + return ev->ev_callback; +} + static void ev_x_cb (struct event *ev, int revents) { @@ -332,9 +357,7 @@ int event_base_loop (struct event_base *base, int flags) { dLOOPbase; - ev_run (EV_A_ flags); - - return 0; + return !ev_run (EV_A_ flags); } int event_base_dispatch (struct event_base *base) @@ -1,7 +1,7 @@ /* * libevent compatibility header, only core events supported * - * Copyright (c) 2007,2008,2010 Marc Alexander Lehmann <libev@schmorp.de> + * Copyright (c) 2007,2008,2010,2012 Marc Alexander Lehmann <libev@schmorp.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- @@ -75,6 +75,8 @@ struct event_base; #define EVLIST_INTERNAL 0x10 #define EVLIST_INIT 0x80 +typedef void (*event_callback_fn)(int, short, void *); + struct event { /* libev watchers we map onto */ @@ -86,7 +88,7 @@ struct event /* compatibility slots */ struct event_base *ev_base; - void (*ev_callback)(int, short, void *arg); + event_callback_fn ev_callback; void *ev_arg; int ev_fd; int ev_pri; @@ -95,9 +97,12 @@ struct event short ev_events; }; +event_callback_fn event_get_callback (const struct event *ev); + #define EV_READ EV_READ #define EV_WRITE EV_WRITE #define EV_PERSIST 0x10 +#define EV_ET 0x20 /* nop */ #define EVENT_SIGNAL(ev) ((int) (ev)->ev_fd) #define EVENT_FD(ev) ((int) (ev)->ev_fd) @@ -152,6 +157,8 @@ int event_pending (struct event *ev, short, struct timeval *tv); int event_priority_init (int npri); int event_priority_set (struct event *ev, int pri); +struct event_base *event_base_new (void); +const char *event_base_get_method (const struct event_base *); int event_base_set (struct event_base *base, struct event *ev); int event_base_loop (struct event_base *base, int); int event_base_loopexit (struct event_base *base, struct timeval *tv); |