--- libev/ev.pod 2011/01/10 14:36:44 1.353
+++ libev/ev.pod 2013/02/23 23:06:40 1.426
@@ -60,7 +60,7 @@
// now wait for events to arrive
ev_run (loop, 0);
- // unloop was called, so exit
+ // break was called, so exit
return 0;
}
@@ -84,9 +84,9 @@
This manual tries to be very detailed, but unfortunately, this also makes
it very long. If you just want to know the basics of libev, I suggest
-reading L, then the L above and
-look up the missing functions in L and the C and
-C sections in L.
+reading L , then the L above and
+look up the missing functions in L and the C and
+C sections in L.
=head1 ABOUT LIBEV
@@ -176,13 +176,19 @@
Returns the current time as libev would use it. Please note that the
C function is usually faster and also often returns the timestamp
you actually want to know. Also interesting is the combination of
-C and C.
+C and C.
=item ev_sleep (ev_tstamp interval)
-Sleep for the given interval: The current thread will be blocked until
-either it is interrupted or the given time interval has passed. Basically
-this is a sub-second-resolution C.
+Sleep for the given interval: The current thread will be blocked
+until either it is interrupted or the given time interval has
+passed (approximately - it might return a bit earlier even if not
+interrupted). Returns immediately if C<< interval <= 0 >>.
+
+Basically this is a sub-second-resolution C.
+
+The range of the C is limited - libev only guarantees to work
+with sleep times of up to one day (C<< interval <= 86400 >>).
=item int ev_version_major ()
@@ -243,7 +249,7 @@
See the description of C watchers for more info.
-=item ev_set_allocator (void *(*cb)(void *ptr, long size))
+=item ev_set_allocator (void *(*cb)(void *ptr, long size) throw ())
Sets the allocation function to use (the prototype is similar - the
semantics are identical to the C C89/SuS/POSIX function). It is
@@ -279,7 +285,7 @@
...
ev_set_allocator (persistent_realloc);
-=item ev_set_syserr_cb (void (*cb)(const char *msg))
+=item ev_set_syserr_cb (void (*cb)(const char *msg) throw ())
Set the callback function to call on a retryable system call error (such
as failed select, poll, epoll_wait). The message is a printable string
@@ -437,13 +443,16 @@
=item C
When this flag is specified, then libev will avoid to modify the signal
-mask. Specifically, this means you ahve to make sure signals are unblocked
+mask. Specifically, this means you have to make sure signals are unblocked
when you want to receive them.
This behaviour is useful when you want to do your own signal handling, or
want to handle signals only in specific threads and want to avoid libev
unblocking the signals.
+It's also required by POSIX in a threaded program, as libev calls
+C, whose behaviour is officially unspecified.
+
This flag's behaviour will become the default in future versions of libev.
=item C (value 1, portable select backend)
@@ -482,10 +491,10 @@
Use the linux-specific epoll(7) interface (for both pre- and post-2.6.9
kernels).
-For few fds, this backend is a bit little slower than poll and select,
-but it scales phenomenally better. While poll and select usually scale
-like O(total_fds) where n is the total number of fds (or the highest fd),
-epoll scales either O(1) or O(active_fds).
+For few fds, this backend is a bit little slower than poll and select, but
+it scales phenomenally better. While poll and select usually scale like
+O(total_fds) where total_fds is the total number of fds (or the highest
+fd), epoll scales either O(1) or O(active_fds).
The epoll mechanism deserves honorable mention as the most misdesigned
of the more advanced event mechanisms: mere annoyances include silently
@@ -498,17 +507,22 @@
set, which can take considerable time (one syscall per file descriptor)
and is of course hard to detect.
-Epoll is also notoriously buggy - embedding epoll fds I work, but
-of course I, and epoll just loves to report events for totally
-I file descriptors (even already closed ones, so one cannot
-even remove them from the set) than registered in the set (especially
-on SMP systems). Libev tries to counter these spurious notifications by
-employing an additional generation counter and comparing that against the
-events to filter out spurious ones, recreating the set when required. Last
+Epoll is also notoriously buggy - embedding epoll fds I work,
+but of course I, and epoll just loves to report events for
+totally I file descriptors (even already closed ones, so
+one cannot even remove them from the set) than registered in the set
+(especially on SMP systems). Libev tries to counter these spurious
+notifications by employing an additional generation counter and comparing
+that against the events to filter out spurious ones, recreating the set
+when required. Epoll also erroneously rounds down timeouts, but gives you
+no way to know when and by how much, so sometimes you have to busy-wait
+because epoll returns immediately despite a nonzero timeout. And last
not least, it also refuses to work with some file descriptors which work
perfectly fine with C (files, many character devices...).
-Epoll is truly the train wreck analog among event poll mechanisms.
+Epoll is truly the train wreck among event poll mechanisms, a frankenpoll,
+cobbled together in a hurry, no thought to design or interaction with
+others. Oh, the pain, will it ever stop...
While stopping, setting and starting an I/O watcher in the same iteration
will result in some caching, there is still a system call per such
@@ -555,9 +569,9 @@
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 C, it still adds up to
-two event changes per incident. Support for C 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 C 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.
This backend usually performs well under most conditions.
@@ -596,11 +610,11 @@
On the negative side, the interface is I - so bizarre that
even sun itself gets it wrong in their code examples: The event polling
-function sometimes returning events to the caller even though an error
+function sometimes returns events to the caller even though an error
occurred, but with no indication whether it has done so or not (yes, it's
-even documented that way) - deadly for edge-triggered interfaces where
-you absolutely have to know whether an event occurred or not because you
-have to re-arm the watcher.
+even documented that way) - deadly for edge-triggered interfaces where you
+absolutely have to know whether an event occurred or not because you have
+to re-arm the watcher.
Fortunately libev seems to be able to work around these idiocies.
@@ -752,7 +766,7 @@
very long time without entering the event loop, updating libev's idea of
the current time is a good idea.
-See also L in the C section.
+See also L in the C section.
=item ev_suspend (loop)
@@ -780,18 +794,22 @@
Calling C/C has the side effect of updating the
event loop time (see C).
-=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.
If the flags argument is specified as C<0>, it will keep handling events
until either no event watchers are active anymore or C 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 again").
+
Please note that an explicit C 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
@@ -799,8 +817,8 @@
of relying on its watchers stopping correctly, that is truly a thing of
beauty.
-This function is also I exception-safe - you can break out of
-a C call by calling C in a callback, throwing a C++
+This function is I exception-safe - you can break out of a
+C call by calling C in a callback, throwing a C++
exception and so on. This does not decrement the C value, nor
will it clear any outstanding C breaks.
@@ -822,7 +840,9 @@
own C"). However, a pair of C/C watchers is
usually a better approach for this kind of thing.
-Here are the gory details of what C does:
+Here are the gory details of what C does (this is for your
+understanding, not a guarantee that things will work exactly like this in
+future versions):
- Increment loop depth.
- Reset the ev_break status.
@@ -865,7 +885,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_run (my_loop, 0);
- ... jobs done or somebody called unloop. yeah!
+ ... jobs done or somebody called break. yeah!
=item ev_break (loop, how)
@@ -938,10 +958,11 @@
By setting a higher I you allow libev to spend more
time collecting I/O events, so you can handle more events per iteration,
at the cost of increasing latency. Timeouts (both C and
-C) will be not affected. Setting this to a non-null value will
+C) will not be affected. Setting this to a non-null value will
introduce an additional C call into most loop iterations. The
sleep time ensures that libev will not poll for I/O events more often then
-once per this interval, on average.
+once per this interval, on average (as long as the host time resolution is
+good enough).
Likewise, by setting a higher I you allow libev
to spend more time collecting timeouts, at the expense of increased
@@ -997,7 +1018,7 @@
If you want to reset the callback, use C as new
callback.
-=item ev_set_loop_release_cb (loop, void (*release)(EV_P), void (*acquire)(EV_P))
+=item ev_set_loop_release_cb (loop, void (*release)(EV_P) throw (), void (*acquire)(EV_P) throw ())
Sometimes you want to share the same loop between multiple threads. This
can be done relatively simply by putting mutex_lock/unlock calls around
@@ -1005,7 +1026,7 @@
However, C can run an indefinite time, so it is not feasible
to wait for it to return. One way around this is to wake up the event
-loop via C and C, another way is to set these
+loop via C and C, another way is to set these
I and I callbacks on the loop.
When set, then C will be called just before the thread is
@@ -1155,13 +1176,18 @@
=item C
-All C watchers are invoked just I C starts
-to gather new events, and all C watchers are invoked just after
-C 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 C watcher might start an idle watcher to keep
-C from blocking).
+All C watchers are invoked just I C starts to
+gather new events, and all C watchers are queued (not invoked)
+just after C has gathered them, but before it queues any callbacks
+for any received events. That means C watchers are the last
+watchers invoked before the event loop sleeps or polls for new events, and
+C watchers will be invoked before any other watchers of the same
+or lower priority within an event loop iteration.
+
+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
+C watcher might start an idle watcher to keep C from
+blocking).
=item C
@@ -1294,7 +1320,7 @@
Returns the callback currently set on the watcher.
-=item ev_cb_set (ev_TYPE *watcher, callback)
+=item ev_set_cb (ev_TYPE *watcher, callback)
Change the callback. You can change the callback at virtually any time
(modulo threads).
@@ -1322,7 +1348,7 @@
The default priority used by watchers when no priority has been set is
always C<0>, which is supposed to not be too high and not be too low :).
-See L, below, for a more thorough treatment of
+See L , below, for a more thorough treatment of
priorities.
=item ev_invoke (loop, ev_TYPE *watcher, int revents)
@@ -1357,70 +1383,8 @@
=back
-=head2 ASSOCIATING CUSTOM DATA WITH A WATCHER
-
-Each watcher has, by default, a member C that you can change
-and read at any time: libev will completely ignore it. This can be used
-to associate arbitrary data with your watcher. If you need more data and
-don't want to allocate memory and store a pointer to it in that data
-member, you can also "subclass" the watcher type and provide your own
-data:
-
- struct my_io
- {
- ev_io io;
- int otherfd;
- void *somedata;
- struct whatever *mostinteresting;
- };
-
- ...
- struct my_io w;
- ev_io_init (&w.io, my_cb, fd, EV_READ);
-
-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, 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.
-
-Another common scenario is to use some data structure with multiple
-embedded watchers:
-
- 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: Either you store the address of your C struct
-in the C member of the watcher (for woozies), or you need to use
-some pointer arithmetic using C inside your watchers (for real
-programmers):
-
- #include
-
- static void
- t1_cb (EV_P_ 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_ ev_timer *w, int revents)
- {
- struct my_biggy big = (struct my_biggy *)
- (((char *)w) - offsetof (struct my_biggy, t2));
- }
+See also the L and L idioms.
=head2 WATCHER STATES
@@ -1431,14 +1395,16 @@
=over 4
-=item initialiased
+=item initialised
-Before a watcher can be registered with the event looop it has to be
+Before a watcher can be registered with the event loop it has to be
initialised. This can be done with a call to C, or calls to
C followed by the watcher-specific C function.
-In this state it is simply some block of memory that is suitable for use
-in an event loop. It can be moved around, freed, reused etc. at will.
+In this state it is simply some block of memory that is suitable for
+use in an event loop. It can be moved around, freed, reused etc. at
+will - as long as you either keep the memory contents intact, or call
+C again.
=item started/running/active
@@ -1476,8 +1442,9 @@
freeing it is often a good idea.
While stopped (and not pending) the watcher is essentially in the
-initialised state, that is it can be reused, moved, modified in any way
-you wish.
+initialised state, that is, it can be reused, moved, modified in any way
+you wish (but when you trash the memory block, you need to C
+it again).
=back
@@ -1616,26 +1583,19 @@
descriptors to non-blocking mode is also usually a good idea (but not
required if you know what you are doing).
-If you cannot use non-blocking mode, then force the use of a
-known-to-be-good backend (at the time of this writing, this includes only
-C and C). The same applies to file
-descriptors for which non-blocking operation makes no sense (such as
-files) - libev doesn't guarantee any specific behaviour in that case.
-
Another thing you have to watch out for is that it is quite easy to
-receive "spurious" readiness notifications, that is your callback might
+receive "spurious" readiness notifications, that is, your callback might
be called with C but a subsequent C(2) will actually block
-because there is no data. Not only are some backends known to create a
-lot of those (for example Solaris ports), it is very easy to get into
-this situation even with a relatively standard program structure. Thus
-it is best to always use non-blocking I/O: An extra C(2) returning
-C is far preferable to a program hanging until some data arrives.
+because there is no data. It is very easy to get into this situation even
+with a relatively standard program structure. Thus it is best to always
+use non-blocking I/O: An extra C(2) returning C is far
+preferable to a program hanging until some data arrives.
If you cannot run the fd in non-blocking mode (for example you should
not play around with an Xlib connection), then you have to separately
re-test whether a file descriptor is really ready with a known-to-be good
-interface such as poll (fortunately in our Xlib example, Xlib already
-does this on its own, so its quite safe to use). Some people additionally
+interface such as poll (fortunately in the case of Xlib, it already does
+this on its own, so its quite safe to use). Some people additionally
use C and an interval timer, just to be sure you won't block
indefinitely.
@@ -1673,16 +1633,48 @@
for potentially C'ed file descriptors, or to resort to
C or C.
+=head3 The special problem of files
+
+Many people try to use C (or libev) on file descriptors
+representing files, and expect it to become ready when their program
+doesn't block on disk accesses (which can take a long time on their own).
+
+However, this cannot ever work in the "expected" way - you get a readiness
+notification as soon as the kernel knows whether and how much data is
+there, and in the case of open files, that's always the case, so you
+always get a readiness notification instantly, and your read (or possibly
+write) will still block on the disk I/O.
+
+Another way to view it is that in the case of sockets, pipes, character
+devices and so on, there is another party (the sender) that delivers data
+on its own, but in the case of files, there is no such thing: the disk
+will not send data on its own, simply because it doesn't know what you
+wish to read - you would first have to request some data.
+
+Since files are typically not-so-well supported by advanced notification
+mechanism, libev tries hard to emulate POSIX behaviour with respect
+to files, even though you should not use it. The reason for this is
+convenience: sometimes you want to watch STDIN or STDOUT, which is
+usually a tty, often a pipe, but also sometimes files or special devices
+(for example, C on Linux works with F but not with
+F), and even though the file might better be served with
+asynchronous I/O instead of with non-blocking I/O, it is still useful when
+it "just works" instead of freezing.
+
+So avoid file descriptors pointing to files when you know it (e.g. use
+libeio), but use them when it is convenient, e.g. for STDIN/STDOUT, or
+when you rarely read from a file instead of from a socket, and want to
+reuse the same code path.
+
=head3 The special problem of fork
Some backends (epoll, kqueue) do not support C at all or exhibit
useless behaviour. Libev fully supports fork, but needs to be told about
-it in the child.
+it in the child if you want to continue to use it in the child.
-To support fork in your programs, you either have to call
-C or C after a fork in the child,
-enable C, or resort to C or
-C.
+To support fork in your child processes, you have to call C after a fork in the child, enable C, or resort to
+C or C.
=head3 The special problem of SIGPIPE
@@ -1790,10 +1782,11 @@
The callback is guaranteed to be invoked only I its timeout has
passed (not I, so on systems with very low-resolution clocks this
-might introduce a small delay). If multiple timers become ready during the
-same loop iteration then the ones with earlier time-out values are invoked
-before ones of the same priority with later time-out values (but this is
-no longer true when a callback calls C recursively).
+might introduce a small delay, see "the special problem of being too
+early", below). If multiple timers become ready during the same loop
+iteration then the ones with earlier time-out values are invoked before
+ones of the same priority with later time-out values (but this is no
+longer true when a callback calls C recursively).
=head3 Be smart about timeouts
@@ -1878,63 +1871,77 @@
but remember the time of last activity, and check for a real timeout only
within the callback:
+ ev_tstamp timeout = 60.;
ev_tstamp last_activity; // time of last activity
+ ev_timer timer;
static void
callback (EV_P_ ev_timer *w, int revents)
{
- ev_tstamp now = ev_now (EV_A);
- ev_tstamp timeout = last_activity + 60.;
+ // calculate when the timeout would happen
+ ev_tstamp after = last_activity - ev_now (EV_A) + timeout;
- // if last_activity + 60. is older than now, we did time out
- if (timeout < now)
+ // if negative, it means we the timeout already occurred
+ if (after < 0.)
{
// timeout occurred, take action
}
else
{
- // callback was invoked, but there was some activity, re-arm
- // the watcher to fire in last_activity + 60, which is
- // guaranteed to be in the future, so "again" is positive:
- w->repeat = timeout - now;
- ev_timer_again (EV_A_ w);
+ // callback was invoked, but there was some recent
+ // activity. simply restart the timer to time out
+ // after "after" seconds, which is the earliest time
+ // the timeout can occur.
+ ev_timer_set (w, after, 0.);
+ ev_timer_start (EV_A_ w);
}
}
-To summarise the callback: first calculate the real timeout (defined
-as "60 seconds after the last activity"), then check if that time has
-been reached, which means something I, in fact, time out. Otherwise
-the callback was invoked too early (C is in the future), so
-re-schedule the timer to fire at that future time, to see if maybe we have
-a timeout then.
-
-Note how C is used, taking advantage of the
-C optimisation when the timer is already running.
+To summarise the callback: first calculate in how many seconds the
+timeout will occur (by calculating the absolute time when it would occur,
+C, and subtracting the current time, C from that).
+
+If this value is negative, then we are already past the timeout, i.e. we
+timed out, and need to do whatever is needed in this case.
+
+Otherwise, we now the earliest time at which the timeout would trigger,
+and simply start the timer with this timeout value.
+
+In other words, each time the callback is invoked it will check whether
+the timeout occurred. If not, it will simply reschedule itself to check
+again at the earliest time it could time out. Rinse. Repeat.
This scheme causes more callback invocations (about one every 60 seconds
minus half the average time between activity), but virtually no calls to
libev to change the timeout.
-To start the timer, simply initialise the watcher and set C
-to the current time (meaning we just have some activity :), then call the
-callback, which will "do the right thing" and start the timer:
-
- ev_init (timer, callback);
- last_activity = ev_now (loop);
- callback (loop, timer, EV_TIMER);
+To start the machinery, simply initialise the watcher and set
+C to the current time (meaning there was some activity just
+now), then call the callback, which will "do the right thing" and start
+the timer:
+
+ last_activity = ev_now (EV_A);
+ ev_init (&timer, callback);
+ callback (EV_A_ &timer, 0);
-And when there is some activity, simply store the current time in
+When there is some activity, simply store the current time in
C, no libev calls at all:
- last_activity = ev_now (loop);
+ if (activity detected)
+ last_activity = ev_now (EV_A);
+
+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 again do the right thing (for example, time out immediately :).
+
+ timeout = new_value;
+ ev_timer_stop (EV_A_ &timer);
+ callback (EV_A_ &timer, 0);
This technique is slightly more complex, but in most cases where the
time-out is unlikely to be triggered, much more efficient.
-Changing the timeout is trivial as well (if it isn't hard-coded in the
-callback :) - just change the timeout and invoke the callback, which will
-fix things for you.
-
=item 4. Wee, just use a double-linked list for your timeouts.
If there is not one request, but many thousands (millions...), all
@@ -1970,10 +1977,47 @@
off after the first million or so of active timers, i.e. it's usually
overkill :)
+=head3 The special problem of being too early
+
+If you ask a timer to call your callback after three seconds, then
+you expect it to be invoked after three seconds - but of course, this
+cannot be guaranteed to infinite precision. Less obviously, it cannot be
+guaranteed to any precision by libev - imagine somebody suspending the
+process with a STOP signal for a few hours for example.
+
+So, libev tries to invoke your callback as soon as possible I the
+delay has occurred, but cannot guarantee this.
+
+A less obvious failure mode is calling your callback too early: many event
+loops compare timestamps with a "elapsed delay >= requested delay", but
+this can cause your callback to be invoked much earlier than you would
+expect.
+
+To see why, imagine a system with a clock that only offers full second
+resolution (think windows if you can't come up with a broken enough OS
+yourself). If you schedule a one-second timer at the time 500.9, then the
+event loop will schedule your timeout to elapse at a system time of 500
+(500.9 truncated to the resolution) + 1, or 501.
+
+If an event library looks at the timeout 0.1s later, it will see "501 >=
+501" and invoke the callback 0.1s after it was started, even though a
+one-second delay was requested - this is being "too early", despite best
+intentions.
+
+This is the reason why libev will never invoke the callback if the elapsed
+delay equals the requested delay, but only when the elapsed delay is
+larger than the requested delay. In the example above, libev would only invoke
+the callback at system time 502, or 1.1s after the timer was started.
+
+So, while libev cannot guarantee that your callback will be invoked
+exactly when requested, it I and I guarantee that the requested
+delay has actually elapsed, or in other words, it always errs on the "too
+late" side of things.
+
=head3 The special problem of time updates
-Establishing the current time is a costly operation (it usually takes at
-least two system calls): EV therefore updates its idea of the current
+Establishing the current time is a costly operation (it usually takes
+at least one system call): EV therefore updates its idea of the current
time only before and after C collects new events, which causes a
growing difference between C and C when handling
lots of events in one iteration.
@@ -1990,6 +2034,39 @@
update of the time returned by C by calling C.
+=head3 The special problem of unsynchronised clocks
+
+Modern systems have a variety of clocks - libev itself uses the normal
+"wall clock" clock and, if available, the monotonic clock (to avoid time
+jumps).
+
+Neither of these clocks is synchronised with each other or any other clock
+on the system, so C might return a considerably different time
+than C or C. On a GNU/Linux system, for example,
+a call to C might return a second count that is one higher
+than a directly following call to C.
+
+The moral of this is to only compare libev-related timestamps with
+C and C, at least if you want better precision than
+a second or so.
+
+One more problem arises due to this lack of synchronisation: if libev uses
+the system monotonic clock and you compare timestamps from C
+or C from when you started your timer and when your callback is
+invoked, you will find that sometimes the callback is a bit "early".
+
+This is because Cs work in real time, not wall clock time, so
+libev makes sure your callback is not invoked before the delay happened,
+I, not the system clock.
+
+If your timeouts are based on a physical timescale (e.g. "time out this
+connection after 100 seconds") then this shouldn't bother you as it is
+exactly the right behaviour.
+
+If you want to compare wall clock/system timestamps to your timers, then
+you need to use Cs, as these are based on the wall clock
+time, where your comparisons will always generate correct results.
+
=head3 The special problems of suspended animation
When you leave the server world it is quite customary to hit machines that
@@ -2042,17 +2119,26 @@
=item ev_timer_again (loop, ev_timer *)
-This will act as if the timer timed out and restart it again if it is
-repeating. The exact semantics are:
+This will act as if the timer timed out, and restarts it again if it is
+repeating. It basically works like calling C, updating the
+timeout to the C value and calling C.
+
+The exact semantics are as in the following rules, all of which will be
+applied to the watcher:
-If the timer is pending, its pending status is cleared.
+=over 4
-If the timer is started but non-repeating, stop it (as if it timed out).
+=item If the timer is pending, the pending status is always cleared.
-If the timer is repeating, either start it if necessary (with the
-C value), or reset the running timer to the C value.
+=item If the timer is started but non-repeating, stop it (as if it timed
+out, without invoking it).
-This sounds a bit complicated, see L, above, for a
+=item If the timer is repeating, make the C value the new timeout
+and start the timer, if necessary.
+
+=back
+
+This sounds a bit complicated, see L , above, for a
usage example.
=item ev_tstamp ev_timer_remaining (loop, ev_timer *)
@@ -2182,9 +2268,12 @@
C will try to run the callback in this mode at the next possible
time where C, regardless of any time jumps.
-For numerical stability it is preferable that the C value is near
-C (the current time), but there is no range requirement for
-this value, and in fact is often specified as zero.
+The C I be positive, and for numerical stability, the
+interval value should be higher than C<1/8192> (which is around 100
+microseconds) and C should be higher than C<0> and should have
+at most a similar magnitude as the current time (say, within a factor of
+ten). Typical values for offset are, in fact, C<0> or something between
+C<0> and C, which is also the recommended range.
Note also that there is an upper limit to how often a timer can fire (CPU
speed for example), so if C is very small then timing stability
@@ -2337,7 +2426,8 @@
Both the signal mask (C) and the signal disposition
(C) are unspecified after starting a signal watcher (and after
stopping it again), that is, libev might or might not block the signal,
-and might or might not set or restore the installed signal handler.
+and might or might not set or restore the installed signal handler (but
+see C).
While this does not matter for the signal disposition (libev never
sets signals to C, so handlers will be reset to C on
@@ -2518,8 +2608,9 @@
This watches a file system path for attribute changes. That is, it calls
C on that path in regular intervals (or when the OS says it changed)
-and sees if it changed compared to the last time, invoking the callback if
-it did.
+and sees if it changed compared to the last time, invoking the callback
+if it did. Starting the watcher C's the file, so only changes that
+happen after the watcher has been started will be reported.
The path does not need to exist: changing from "path exists" to "path does
not exist" is a status change like any other. The condition "path does not
@@ -2759,6 +2850,20 @@
"pseudo-background processing", or delay processing stuff to after the
event loop has handled all outstanding events.
+=head3 Abusing an C watcher for its side-effect
+
+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.
+
+This mode of operation can be useful together with an C watcher,
+to do something on each event loop iteration - for example to balance load
+between different connections.
+
+See L for a longer
+example.
+
=head3 Watcher-Specific Functions and Data Members
=over 4
@@ -2779,7 +2884,12 @@
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.
}
@@ -2791,7 +2901,7 @@
=head2 C and C - 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.
@@ -2829,9 +2939,10 @@
loop from blocking if lower-priority coroutines are active, thus mapping
low-priority coroutines to idle/background tasks).
-It is recommended to give C watchers highest (C)
-priority, to ensure that they are being run before any other watchers
-after the poll (this doesn't matter for C watchers).
+When used for this purpose, it is recommended to give C watchers
+highest (C) priority, to ensure that they are being run before
+any other watchers after the poll (this doesn't matter for C
+watchers).
Also, C watchers (and C watchers, too) should not
activate ("feed") events into libev. While libev fully supports this, they
@@ -2841,6 +2952,25 @@
C watcher ran (always remind yourself to coexist peacefully with
others).
+=head3 Abusing an C watcher for its side-effect
+
+C (and less often also C) 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.
+
+Using an C 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 C watcher will not be invoked.
+
+This is where C watchers come in handy - all you need is a
+single global idle watcher that is active as long as you have one active
+C watcher. The C watcher makes sure the event loop
+will not sleep, and the C watcher makes sure a callback gets
+invoked. Neither watcher alone can do that.
+
=head3 Watcher-Specific Functions and Data Members
=over 4
@@ -3050,7 +3180,7 @@
=item ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)
-=item ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)
+=item ev_embed_set (ev_embed *, struct ev_loop *embedded_loop)
Configures the watcher to embed the given loop, which must be
embeddable. If the callback is C<0>, then C will be
@@ -3123,11 +3253,11 @@
Fork watchers are called when a C was detected (usually because
whoever is a good citizen cared to tell libev about it by calling
-C or C). The invocation is done before the
-event loop blocks next and before C watchers are being called,
-and only in the child after the fork. If whoever good citizen calling
-C cheats and calls it in the wrong process, the fork
-handlers will be invoked, too, of course.
+C). The invocation is done before the event loop blocks next
+and before C watchers are being called, and only in the child
+after the fork. If whoever good citizen calling C cheats
+and calls it in the wrong process, the fork handlers will be invoked, too,
+of course.
=head3 The special problem of life after fork - how is it possible?
@@ -3218,7 +3348,7 @@
=head2 C - how to wake up an event loop
-In general, you cannot use an C from multiple threads or other
+In general, you cannot use an C from multiple threads or other
asynchronous sources such as signal handlers (as opposed to multiple event
loops - those are of course safe to use in different threads).
@@ -3230,14 +3360,11 @@
This functionality is very similar to C 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
-C calls). In fact, you could use signal watchers as a kind
+C calls). In fact, you could use signal watchers as a kind
of "global async watchers" by using a watcher on an otherwise unused
signal, and C to signal this watcher from another thread,
even without knowing which loop owns the signal.
-Unlike C watchers, C works with any event loop, not
-just the default loop.
-
=head3 Queueing
C does not support queueing of data in any way. The reason
@@ -3338,19 +3465,24 @@
=item ev_async_send (loop, ev_async *)
Sends/signals/activates the given C watcher, that is, feeds
-an C event on the watcher into the event loop. Unlike
-C, this call is safe to do from other threads, signal or
-similar contexts (see the discussion of C in the embedding
-section below on what exactly this means).
+an C event on the watcher into the event loop, and instantly
+returns.
+
+Unlike C, this call is safe to do from other threads,
+signal or similar contexts (see the discussion of C in the
+embedding section below on what exactly this means).
Note that, as with other watchers in libev, multiple events might get
-compressed into a single callback invocation (another way to look at this
-is that C watchers are level-triggered, set on C,
-reset when the event loop detects that).
-
-This call incurs the overhead of a system call only once per event loop
-iteration, so while the overhead might be noticeable, it doesn't apply to
-repeated calls to C for the same event loop.
+compressed into a single callback invocation (another way to look at
+this is that C watchers are level-triggered: they are set on
+C, reset when the event loop detects that).
+
+This call incurs the overhead of at most one extra system call per event
+loop iteration, if the event loop is blocked, and no syscall at all if
+the event loop (or your program) is processing events. That means that
+repeated calls are basically free (there is no need to avoid calls for
+performance reasons) and that the overhead becomes smaller (typically
+zero) under load.
=item bool = ev_async_pending (ev_async *)
@@ -3415,7 +3547,7 @@
=item ev_feed_fd_event (loop, int fd, int revents)
Feed an event on the given fd, as if a file descriptor backend detected
-the given events it.
+the given events.
=item ev_feed_signal_event (loop, int signum)
@@ -3431,9 +3563,115 @@
obvious. Note that examples are sprinkled over the whole manual, and this
section only contains stuff that wouldn't fit anywhere else.
-=over 4
+=head2 ASSOCIATING CUSTOM DATA WITH A WATCHER
-=item Model/nested event loop invocations and exit conditions.
+Each watcher has, by default, a C member that you can read
+or modify at any time: libev will completely ignore it. This can be used
+to associate arbitrary data with your watcher. If you need more data and
+don't want to allocate memory separately and store a pointer to it in that
+data member, you can also "subclass" the watcher type and provide your own
+data:
+
+ struct my_io
+ {
+ ev_io io;
+ int otherfd;
+ void *somedata;
+ struct whatever *mostinteresting;
+ };
+
+ ...
+ struct my_io w;
+ ev_io_init (&w.io, my_cb, fd, EV_READ);
+
+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, ev_io *w_, int revents)
+ {
+ struct my_io *w = (struct my_io *)w_;
+ ...
+ }
+
+More interesting and less C-conformant ways of casting your callback
+function type instead have been omitted.
+
+=head2 BUILDING YOUR OWN COMPOSITE WATCHERS
+
+Another common scenario is to use some data structure with multiple
+embedded watchers, in effect creating your own watcher that combines
+multiple libev event sources into one "super-watcher":
+
+ 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: Either you store the address of your C struct in
+the C member of the watcher (for woozies or C++ coders), or you need
+to use some pointer arithmetic using C inside your watchers (for
+real programmers):
+
+ #include
+
+ static void
+ t1_cb (EV_P_ 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_ ev_timer *w, int revents)
+ {
+ struct my_biggy big = (struct my_biggy *)
+ (((char *)w) - offsetof (struct my_biggy, t2));
+ }
+
+=head2 AVOIDING FINISHING BEFORE RETURNING
+
+Often you have structures like this in event-based programs:
+
+ callback ()
+ {
+ free (request);
+ }
+
+ request = start_new_request (..., callback);
+
+The intent is to start some "lengthy" operation. The C could be
+used to cancel the operation, or do other things with it.
+
+It's not uncommon to have code paths in C that
+immediately invoke the callback, for example, to report errors. Or you add
+some caching layer that finds that it can skip the lengthy aspects of the
+operation and simply invoke the callback with the result.
+
+The problem here is that this will happen I C
+has returned, so C is not set.
+
+Even if you pass the request by some safer means to the callback, you
+might want to do something to the request after starting it, such as
+canceling it, which probably isn't working so well when the callback has
+already been invoked.
+
+A common way around all these issues is to make sure that
+C I returns before the callback is invoked. If
+C immediately knows the result, it can artificially
+delay invoking the callback by using a C or C watcher for
+example, or more sneakily, by reusing an existing (stopped) watcher and
+pushing it into the pending queue:
+
+ ev_set_cb (watcher, callback);
+ ev_feed_event (EV_A_ watcher, 0);
+
+This way, C can safely return before the callback is
+invoked, while not delaying callback invocation too much.
+
+=head2 MODEL/NESTED EVENT LOOP INVOCATIONS AND EXIT CONDITIONS
Often (especially in GUI toolkits) there are places where you have
I interaction, which is most easily implemented by recursively
@@ -3443,7 +3681,7 @@
main C call, but not the nested one (e.g. user clicked "Quit", but
a modal "Are you sure?" dialog is still waiting), or just the nested one
and not the main one (e.g. user clocked "Ok" in a modal dialog), or some
-other combination: In these cases, C will not work alone.
+other combination: In these cases, a simple C will not work.
The solution is to maintain "break this loop" variable for each C
invocation, and use a loop around C until the condition is
@@ -3455,7 +3693,7 @@
while (!exit_main_loop)
ev_run (EV_DEFAULT_ EVRUN_ONCE);
- // in a model watcher
+ // in a modal watcher
int exit_nested_loop = 0;
while (!exit_nested_loop)
@@ -3472,7 +3710,201 @@
// exit both
exit_main_loop = exit_nested_loop = 1;
-=back
+=head2 THREAD LOCKING EXAMPLE
+
+Here is a fictitious example of how to run an event loop in a different
+thread from where callbacks are being invoked and watchers are
+created/added/removed.
+
+For a real-world example, see the C perl module,
+which uses exactly this technique (which is suited for many high-level
+languages).
+
+The example uses a pthread mutex to protect the loop data, a condition
+variable to wait for callback invocations, an async watcher to notify the
+event loop thread and an unspecified mechanism to wake up the main thread.
+
+First, you need to associate some data with the event loop:
+
+ typedef struct {
+ mutex_t lock; /* global loop lock */
+ ev_async async_w;
+ thread_t tid;
+ cond_t invoke_cv;
+ } userdata;
+
+ void prepare_loop (EV_P)
+ {
+ // for simplicity, we use a static userdata struct.
+ static userdata u;
+
+ ev_async_init (&u->async_w, async_cb);
+ ev_async_start (EV_A_ &u->async_w);
+
+ pthread_mutex_init (&u->lock, 0);
+ pthread_cond_init (&u->invoke_cv, 0);
+
+ // now associate this with the loop
+ ev_set_userdata (EV_A_ u);
+ ev_set_invoke_pending_cb (EV_A_ l_invoke);
+ ev_set_loop_release_cb (EV_A_ l_release, l_acquire);
+
+ // then create the thread running ev_run
+ pthread_create (&u->tid, 0, l_run, EV_A);
+ }
+
+The callback for the C watcher does nothing: the watcher is used
+solely to wake up the event loop so it takes notice of any new watchers
+that might have been added:
+
+ static void
+ async_cb (EV_P_ ev_async *w, int revents)
+ {
+ // just used for the side effects
+ }
+
+The C and C callbacks simply unlock/lock the mutex
+protecting the loop data, respectively.
+
+ static void
+ l_release (EV_P)
+ {
+ userdata *u = ev_userdata (EV_A);
+ pthread_mutex_unlock (&u->lock);
+ }
+
+ static void
+ l_acquire (EV_P)
+ {
+ userdata *u = ev_userdata (EV_A);
+ pthread_mutex_lock (&u->lock);
+ }
+
+The event loop thread first acquires the mutex, and then jumps straight
+into C:
+
+ void *
+ l_run (void *thr_arg)
+ {
+ struct ev_loop *loop = (struct ev_loop *)thr_arg;
+
+ l_acquire (EV_A);
+ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
+ ev_run (EV_A_ 0);
+ l_release (EV_A);
+
+ return 0;
+ }
+
+Instead of invoking all pending watchers, the C callback will
+signal the main thread via some unspecified mechanism (signals? pipe
+writes? C?) and then waits until all pending watchers
+have been called (in a while loop because a) spurious wakeups are possible
+and b) skipping inter-thread-communication when there are no pending
+watchers is very beneficial):
+
+ static void
+ l_invoke (EV_P)
+ {
+ userdata *u = ev_userdata (EV_A);
+
+ while (ev_pending_count (EV_A))
+ {
+ wake_up_other_thread_in_some_magic_or_not_so_magic_way ();
+ pthread_cond_wait (&u->invoke_cv, &u->lock);
+ }
+ }
+
+Now, whenever the main thread gets told to invoke pending watchers, it
+will grab the lock, call C and then signal the loop
+thread to continue:
+
+ static void
+ real_invoke_pending (EV_P)
+ {
+ userdata *u = ev_userdata (EV_A);
+
+ pthread_mutex_lock (&u->lock);
+ ev_invoke_pending (EV_A);
+ pthread_cond_signal (&u->invoke_cv);
+ pthread_mutex_unlock (&u->lock);
+ }
+
+Whenever you want to start/stop a watcher or do other modifications to an
+event loop, you will now have to lock:
+
+ ev_timer timeout_watcher;
+ userdata *u = ev_userdata (EV_A);
+
+ ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
+
+ pthread_mutex_lock (&u->lock);
+ ev_timer_start (EV_A_ &timeout_watcher);
+ ev_async_send (EV_A_ &u->async_w);
+ pthread_mutex_unlock (&u->lock);
+
+Note that sending the C watcher is required because otherwise
+an event loop currently blocking in the kernel will have no knowledge
+about the newly added timer. By waking up the loop it will pick up any new
+watchers in the next event loop iteration.
+
+=head2 THREADS, COROUTINES, CONTINUATIONS, QUEUES... INSTEAD OF CALLBACKS
+
+While the overhead of a callback that e.g. schedules a thread is small, it
+is still an overhead. If you embed libev, and your main usage is with some
+kind of threads or coroutines, you might want to customise libev so that
+doesn't need callbacks anymore.
+
+Imagine you have coroutines that you can switch to using a function
+C