--- libev/ev.3 2012/04/22 10:14:20 1.92 +++ libev/ev.3 2012/05/06 13:05:35 1.93 @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "LIBEV 3" -.TH LIBEV 3 "2012-04-19" "libev-4.11" "libev - high performance full featured event loop" +.TH LIBEV 3 "2012-05-06" "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 @@ -1301,13 +1301,18 @@ .el .IP "\f(CWEV_CHECK\fR" 4 .IX Item "EV_CHECK" .PD -All \f(CW\*(C`ev_prepare\*(C'\fR watchers are invoked just \fIbefore\fR \f(CW\*(C`ev_run\*(C'\fR starts -to gather new events, and all \f(CW\*(C`ev_check\*(C'\fR watchers are invoked just after -\&\f(CW\*(C`ev_run\*(C'\fR has gathered them, but before it invokes any callbacks for any -received events. Callbacks of both watcher types can start and stop as -many watchers as they want, and all of them will be taken into account -(for example, a \f(CW\*(C`ev_prepare\*(C'\fR watcher might start an idle watcher to keep -\&\f(CW\*(C`ev_run\*(C'\fR from blocking). +All \f(CW\*(C`ev_prepare\*(C'\fR watchers are invoked just \fIbefore\fR \f(CW\*(C`ev_run\*(C'\fR starts to +gather new events, and all \f(CW\*(C`ev_check\*(C'\fR watchers are queued (not invoked) +just after \f(CW\*(C`ev_run\*(C'\fR has gathered them, but before it queues any callbacks +for any received events. That means \f(CW\*(C`ev_prepare\*(C'\fR watchers are the last +watchers invoked before the event loop sleeps or polls for new events, and +\&\f(CW\*(C`ev_check\*(C'\fR watchers will be invoked before any other watchers of the same +or lower priority within an event loop iteration. +.Sp +Callbacks of both watcher types can start and stop as many watchers as +they want, and all of them will be taken into account (for example, a +\&\f(CW\*(C`ev_prepare\*(C'\fR watcher might start an idle watcher to keep \f(CW\*(C`ev_run\*(C'\fR from +blocking). .ie n .IP """EV_EMBED""" 4 .el .IP "\f(CWEV_EMBED\fR" 4 .IX Item "EV_EMBED" @@ -1438,8 +1443,8 @@ .IP "callback ev_cb (ev_TYPE *watcher)" 4 .IX Item "callback ev_cb (ev_TYPE *watcher)" Returns the callback currently set on the watcher. -.IP "ev_cb_set (ev_TYPE *watcher, callback)" 4 -.IX Item "ev_cb_set (ev_TYPE *watcher, callback)" +.IP "ev_set_cb (ev_TYPE *watcher, callback)" 4 +.IX Item "ev_set_cb (ev_TYPE *watcher, callback)" Change the callback. You can change the callback at virtually any time (modulo threads). .IP "ev_set_priority (ev_TYPE *watcher, int priority)" 4 @@ -1996,7 +2001,7 @@ \& // calculate when the timeout would happen \& ev_tstamp after = last_activity \- ev_now (EV_A) + timeout; \& -\& // if negative, it means we the timeout already occured +\& // if negative, it means we the timeout already occurred \& if (after < 0.) \& { \& // timeout occurred, take action @@ -2025,7 +2030,7 @@ and simply start the timer with this timeout value. .Sp In other words, each time the callback is invoked it will check whether -the timeout cocured. If not, it will simply reschedule itself to check +the timeout occurred. If not, it will simply reschedule itself to check again at the earliest time it could time out. Rinse. Repeat. .Sp This scheme causes more callback invocations (about one every 60 seconds @@ -2053,7 +2058,7 @@ .Sp When your timeout value changes, then the timeout can be changed by simply providing a new value, stopping the timer and calling the callback, which -will agaion do the right thing (for example, time out immediately :). +will again do the right thing (for example, time out immediately :). .Sp .Vb 3 \& timeout = new_value; @@ -2979,6 +2984,21 @@ \&\*(L"pseudo-background processing\*(R", or delay processing stuff to after the event loop has handled all outstanding events. .PP +\fIAbusing an \f(CI\*(C`ev_idle\*(C'\fI watcher for its side-effect\fR +.IX Subsection "Abusing an ev_idle watcher for its side-effect" +.PP +As long as there is at least one active idle watcher, libev will never +sleep unnecessarily. Or in other words, it will loop as fast as possible. +For this to work, the idle watcher doesn't need to be invoked at all \- the +lowest priority will do. +.PP +This mode of operation can be useful together with an \f(CW\*(C`ev_check\*(C'\fR watcher, +to do something on each event loop iteration \- for example to balance load +between different connections. +.PP +See \*(L"Abusing an ev_check watcher for its side-effect\*(R" for a longer +example. +.PP \fIWatcher-Specific Functions and Data Members\fR .IX Subsection "Watcher-Specific Functions and Data Members" .IP "ev_idle_init (ev_idle *, callback)" 4 @@ -2993,11 +3013,16 @@ Example: Dynamically allocate an \f(CW\*(C`ev_idle\*(C'\fR watcher, start it, and in the callback, free it. Also, use no error checking, as usual. .PP -.Vb 7 +.Vb 5 \& static void \& idle_cb (struct ev_loop *loop, ev_idle *w, int revents) \& { +\& // stop the watcher +\& ev_idle_stop (loop, w); +\& +\& // now we can free it \& free (w); +\& \& // now do something you wanted to do when the program has \& // no longer anything immediate to do. \& } @@ -3009,7 +3034,7 @@ .ie n .SS """ev_prepare"" and ""ev_check"" \- customise your event loop!" .el .SS "\f(CWev_prepare\fP and \f(CWev_check\fP \- customise your event loop!" .IX Subsection "ev_prepare and ev_check - customise your event loop!" -Prepare and check watchers are usually (but not always) used in pairs: +Prepare and check watchers are often (but not always) used in pairs: prepare watchers get invoked before the process blocks and check watchers afterwards. .PP @@ -3047,9 +3072,10 @@ loop from blocking if lower-priority coroutines are active, thus mapping low-priority coroutines to idle/background tasks). .PP -It is recommended to give \f(CW\*(C`ev_check\*(C'\fR watchers highest (\f(CW\*(C`EV_MAXPRI\*(C'\fR) -priority, to ensure that they are being run before any other watchers -after the poll (this doesn't matter for \f(CW\*(C`ev_prepare\*(C'\fR watchers). +When used for this purpose, it is recommended to give \f(CW\*(C`ev_check\*(C'\fR watchers +highest (\f(CW\*(C`EV_MAXPRI\*(C'\fR) priority, to ensure that they are being run before +any other watchers after the poll (this doesn't matter for \f(CW\*(C`ev_prepare\*(C'\fR +watchers). .PP Also, \f(CW\*(C`ev_check\*(C'\fR watchers (and \f(CW\*(C`ev_prepare\*(C'\fR watchers, too) should not activate (\*(L"feed\*(R") events into libev. While libev fully supports this, they @@ -3059,6 +3085,26 @@ \&\f(CW\*(C`ev_check\*(C'\fR watcher ran (always remind yourself to coexist peacefully with others). .PP +\fIAbusing an \f(CI\*(C`ev_check\*(C'\fI watcher for its side-effect\fR +.IX Subsection "Abusing an ev_check watcher for its side-effect" +.PP +\&\f(CW\*(C`ev_check\*(C'\fR (and less often also \f(CW\*(C`ev_prepare\*(C'\fR) watchers can also be +useful because they are called once per event loop iteration. For +example, if you want to handle a large number of connections fairly, you +normally only do a bit of work for each active connection, and if there +is more work to do, you wait for the next event loop iteration, so other +connections have a chance of making progress. +.PP +Using an \f(CW\*(C`ev_check\*(C'\fR watcher is almost enough: it will be called on the +next event loop iteration. However, that isn't as soon as possible \- +without external events, your \f(CW\*(C`ev_check\*(C'\fR watcher will not be invoked. +.PP +This is where \f(CW\*(C`ev_idle\*(C'\fR watchers come in handy \- all you need is a +single global idle watcher that is active as long as you have one active +\&\f(CW\*(C`ev_check\*(C'\fR watcher. The \f(CW\*(C`ev_idle\*(C'\fR watcher makes sure the event loop +will not sleep, and the \f(CW\*(C`ev_check\*(C'\fR watcher makes sure a callback gets +invoked. Neither watcher alone can do that. +.PP \fIWatcher-Specific Functions and Data Members\fR .IX Subsection "Watcher-Specific Functions and Data Members" .IP "ev_prepare_init (ev_prepare *, callback)" 4 @@ -3446,7 +3492,7 @@ This functionality is very similar to \f(CW\*(C`ev_signal\*(C'\fR watchers, as signals, too, are asynchronous in nature, and signals, too, will be compressed (i.e. the number of callback invocations may be less than the number of -\&\f(CW\*(C`ev_async_sent\*(C'\fR calls). In fact, you could use signal watchers as a kind +\&\f(CW\*(C`ev_async_send\*(C'\fR calls). In fact, you could use signal watchers as a kind of \*(L"global async watchers\*(R" by using a watcher on an otherwise unused signal, and \f(CW\*(C`ev_feed_signal\*(C'\fR to signal this watcher from another thread, even without knowing which loop owns the signal. @@ -3973,7 +4019,7 @@ \& void \& wait_for_event (ev_watcher *w) \& { -\& ev_cb_set (w) = current_coro; +\& ev_set_cb (w, current_coro); \& switch_to (libev_coro); \& } .Ve @@ -3987,7 +4033,7 @@ switching to a coroutine, you push the watcher onto the queue and notify any waiters. .PP -To embed libev, see \s-1EMBEDDING\s0, but in short, it's easiest to create two +To embed libev, see \*(L"\s-1EMBEDDING\s0\*(R", but in short, it's easiest to create two files, \fImy_ev.h\fR and \fImy_ev.c\fR that include the respective libev files: .PP .Vb 4 @@ -4062,7 +4108,7 @@ .Ve .PP The only \s-1API\s0 functions that can currently throw exceptions are \f(CW\*(C`ev_run\*(C'\fR, -\&\f(CW\*(C`ev_inoke\*(C'\fR, \f(CW\*(C`ev_invoke_pending\*(C'\fR and \f(CW\*(C`ev_loop_destroy\*(C'\fR (the latter +\&\f(CW\*(C`ev_invoke\*(C'\fR, \f(CW\*(C`ev_invoke_pending\*(C'\fR and \f(CW\*(C`ev_loop_destroy\*(C'\fR (the latter because it runs cleanup watchers). .PP Throwing exceptions in watcher callbacks is only supported if libev itself @@ -5458,7 +5504,7 @@ .el .IP "\f(CWEV_COMPAT3\fR backwards compatibility mechanism" 4 .IX Item "EV_COMPAT3 backwards compatibility mechanism" The backward compatibility mechanism can be controlled by -\&\f(CW\*(C`EV_COMPAT3\*(C'\fR. See \*(L"\s-1MACROS\s0\*(R" in \s-1PREPROCESSOR\s0 \s-1SYMBOLS\s0 in the \s-1EMBEDDING\s0 +\&\f(CW\*(C`EV_COMPAT3\*(C'\fR. See \*(L"\s-1PREPROCESSOR\s0 \s-1SYMBOLS/MACROS\s0\*(R" in the \*(L"\s-1EMBEDDING\s0\*(R" section. .ie n .IP """ev_default_destroy"" and ""ev_default_fork"" have been removed" 4 .el .IP "\f(CWev_default_destroy\fR and \f(CWev_default_fork\fR have been removed" 4