mirror of /home/gitosis/repositories/libev.git
document the embed watchers
This commit is contained in:
parent
56732f9681
commit
96036f367f
89
ev.pod
89
ev.pod
|
@ -108,6 +108,16 @@ most BSDs and will not be autodetected unless you explicitly request it
|
|||
(assuming you know what you are doing). This is the set of backends that
|
||||
libev will probe for if you specify no backends explicitly.
|
||||
|
||||
=item unsigned int ev_embeddable_backends ()
|
||||
|
||||
Returns the set of backends that are embeddable in other event loops. This
|
||||
is the theoretical, all-platform, value. To find which backends
|
||||
might be supported on the current system, you would need to look at
|
||||
C<ev_embeddable_backends () & ev_supported_backends ()>, likewise for
|
||||
recommended ones.
|
||||
|
||||
See the description of C<ev_embed> watchers for more info.
|
||||
|
||||
=item ev_set_allocator (void *(*cb)(void *ptr, long size))
|
||||
|
||||
Sets the allocation function to use (the prototype is similar to the
|
||||
|
@ -925,6 +935,7 @@ of the C<SIGxxx> constants).
|
|||
|
||||
=back
|
||||
|
||||
|
||||
=head2 C<ev_child> - wait for pid status changes
|
||||
|
||||
Child watchers trigger when your process receives a SIGCHLD in response to
|
||||
|
@ -1008,9 +1019,10 @@ Prepare and check watchers are usually (but not always) used in tandem:
|
|||
prepare watchers get invoked before the process blocks and check watchers
|
||||
afterwards.
|
||||
|
||||
Their main purpose is to integrate other event mechanisms into libev. This
|
||||
could be used, for example, to track variable changes, implement your own
|
||||
watchers, integrate net-snmp or a coroutine library and lots more.
|
||||
Their main purpose is to integrate other event mechanisms into libev and
|
||||
their use is somewhat advanced. This could be used, for example, to track
|
||||
variable changes, implement your own watchers, integrate net-snmp or a
|
||||
coroutine library and lots more.
|
||||
|
||||
This is done by examining in each prepare call which file descriptors need
|
||||
to be watched by the other library, registering C<ev_io> watchers for
|
||||
|
@ -1045,6 +1057,77 @@ macros, but using them is utterly, utterly and completely pointless.
|
|||
Example: *TODO*.
|
||||
|
||||
|
||||
=head2 C<ev_embed> - when one backend isn't enough
|
||||
|
||||
This is a rather advanced watcher type that lets you embed one event loop
|
||||
into another.
|
||||
|
||||
There are primarily two reasons you would want that: work around bugs and
|
||||
prioritise I/O.
|
||||
|
||||
As an example for a bug workaround, the kqueue backend might only support
|
||||
sockets on some platform, so it is unusable as generic backend, but you
|
||||
still want to make use of it because you have many sockets and it scales
|
||||
so nicely. In this case, you would create a kqueue-based loop and embed it
|
||||
into your default loop (which might use e.g. poll). Overall operation will
|
||||
be a bit slower because first libev has to poll and then call kevent, but
|
||||
at least you can use both at what they are best.
|
||||
|
||||
As for prioritising I/O: rarely you have the case where some fds have
|
||||
to be watched and handled very quickly (with low latency), and even
|
||||
priorities and idle watchers might have too much overhead. In this case
|
||||
you would put all the high priority stuff in one loop and all the rest in
|
||||
a second one, and embed the second one in the first.
|
||||
|
||||
As long as the watcher is started it will automatically handle events. The
|
||||
callback will be invoked whenever some events have been handled. You can
|
||||
set the callback to C<0> to avoid having to specify one if you are not
|
||||
interested in that.
|
||||
|
||||
Also, there have not currently been made special provisions for forking:
|
||||
when you fork, you not only have to call C<ev_loop_fork> on both loops,
|
||||
but you will also have to stop and restart any C<ev_embed> watchers
|
||||
yourself.
|
||||
|
||||
Unfortunately, not all backends are embeddable, only the ones returned by
|
||||
C<ev_embeddable_backends> are, which, unfortunately, does not include any
|
||||
portable one.
|
||||
|
||||
So when you want to use this feature you will always have to be prepared
|
||||
that you cannot get an embeddable loop. The recommended way to get around
|
||||
this is to have a separate variables for your embeddable loop, try to
|
||||
create it, and if that fails, use the normal loop for everything:
|
||||
|
||||
struct ev_loop *loop_hi = ev_default_init (0);
|
||||
struct ev_loop *loop_lo = 0;
|
||||
struct ev_embed embed;
|
||||
|
||||
// see if there is a chance of getting one that works
|
||||
// (remember that a flags value of 0 means autodetection)
|
||||
loop_lo = ev_embeddable_backends () & ev_recommended_backends ()
|
||||
? ev_loop_new (ev_embeddable_backends () & ev_recommended_backends ())
|
||||
: 0;
|
||||
|
||||
// if we got one, then embed it, otherwise default to loop_hi
|
||||
if (loop_lo)
|
||||
{
|
||||
ev_embed_init (&embed, 0, loop_lo);
|
||||
ev_embed_start (loop_hi, &embed);
|
||||
}
|
||||
else
|
||||
loop_lo = loop_hi;
|
||||
|
||||
=over 4
|
||||
|
||||
=item ev_embed_init (ev_embed *, callback, struct ev_loop *loop)
|
||||
|
||||
=item ev_embed_set (ev_embed *, callback, struct ev_loop *loop)
|
||||
|
||||
Configures the watcher to embed the given loop, which must be embeddable.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 OTHER FUNCTIONS
|
||||
|
||||
There are some other functions of possible interest. Described. Here. Now.
|
||||
|
|
Loading…
Reference in New Issue