EV

 view release on metacpan or  search on metacpan

libev/ev.pod  view on Meta::CPAN

current event loop) or C<ev_loop_fork> from either C<ev_prepare> or
C<ev_check> watchers. Other loops than the current one are fine,
however. The rationale behind this is that you do not need to check
for recursion in those watchers, i.e. the sequence will always be
C<ev_prepare>, blocking, C<ev_check> so if you have one watcher of each
kind they will always be called in pairs bracketing the blocking call.

Their main purpose is to integrate other event mechanisms into libev and
their use is somewhat advanced. They could be used, for example, to track
variable changes, implement your own watchers, integrate net-snmp or a
coroutine library and lots more. They are also occasionally useful if
you cache some data and want to flush it before blocking (for example,
in X programs you might want to do an C<XFlush ()> in an C<ev_prepare>
watcher).

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 them and starting an C<ev_timer> watcher for any timeouts (many
libraries provide exactly this functionality). Then, in the check watcher,
you check for any events that occurred (by checking the pending status
of all watchers and stopping them) and call back into the library. The
I/O and timer callbacks will never actually be called (but must be valid
nevertheless, because you never know, you know?).

As another example, the Perl Coro module uses these hooks to integrate
coroutines into libev programs, by yielding to other active coroutines
during each prepare and only letting the process block if no coroutines
are ready to run (it's actually more complicated: it only runs coroutines
with priority higher than or equal to the event loop and one coroutine
of lower priority, but only once, using idle watchers to keep the event
loop from blocking if lower-priority coroutines are active, thus mapping
low-priority coroutines to idle/background tasks).

When used for this purpose, it is recommended to give C<ev_check> watchers
highest (C<EV_MAXPRI>) priority, to ensure that they are being run before
any other watchers after the poll (this doesn't matter for C<ev_prepare>
watchers).

Also, C<ev_check> watchers (and C<ev_prepare> watchers, too) should not
activate ("feed") events into libev. While libev fully supports this, they
might get executed before other C<ev_check> watchers did their job. As
C<ev_check> watchers are often used to embed other (non-libev) event

libev/ev.pod  view on Meta::CPAN


Note that sending the C<ev_async> 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<switch_to (coro)>, that libev runs in a coroutine called C<libev_coro>
and that due to some magic, the currently active coroutine is stored in a
global called C<current_coro>. Then you can build your own "wait for libev
event" primitive by changing C<EV_CB_DECLARE> and C<EV_CB_INVOKE> (note
the differing C<;> conventions):

   #define EV_CB_DECLARE(type)   struct my_coro *cb;
   #define EV_CB_INVOKE(watcher) switch_to ((watcher)->cb)

That means instead of having a C callback function, you store the
coroutine to switch to in each watcher, and instead of having libev call
your callback, you instead have it switch to that coroutine.

A coroutine might now wait for an event with a function called
C<wait_for_event>. (the watcher needs to be started, as always, but it doesn't
matter when, or whether the watcher is active or not when this function is
called):

   void
   wait_for_event (ev_watcher *w)
   {
     ev_set_cb (w, current_coro);
     switch_to (libev_coro);
   }

That basically suspends the coroutine inside C<wait_for_event> and
continues the libev coroutine, which, when appropriate, switches back to
this or any other coroutine.

You can do similar tricks if you have, say, threads with an event queue -
instead of storing a coroutine, you store the queue object and instead of
switching to a coroutine, you push the watcher onto the queue and notify
any waiters.

To embed libev, see L</EMBEDDING>, but in short, it's easiest to create two
files, F<my_ev.h> and F<my_ev.c> that include the respective libev files:

   // my_ev.h
   #define EV_CB_DECLARE(type)   struct my_coro *cb;
   #define EV_CB_INVOKE(watcher) switch_to ((watcher)->cb)
   #include "../libev/ev.h"

   // my_ev.c
   #define EV_H "my_ev.h"
   #include "../libev/ev.c"

And then use F<my_ev.h> when you would normally use F<ev.h>, and compile
F<my_ev.c> into your project. When properly specifying include paths, you
can even use F<ev.h> as header file name directly.

libev/ev.pod  view on Meta::CPAN

work in the default loop by registering the signal watcher with the
default loop and triggering an C<ev_async> watcher from the default loop
watcher callback into the event loop interested in the signal.

=back

See also L</THREAD LOCKING EXAMPLE>.

=head3 COROUTINES

Libev is very accommodating to coroutines ("cooperative threads"):
libev fully supports nesting calls to its functions from different
coroutines (e.g. you can call C<ev_run> on the same loop from two
different coroutines, and switch freely between both coroutines running
the loop, as long as you don't confuse yourself). The only exception is
that you must not do this from C<ev_periodic> reschedule callbacks.

Care has been taken to ensure that libev does not keep local state inside
C<ev_run>, and other calls do not usually allow for coroutine switches as
they do not call any callbacks.

=head2 COMPILER WARNINGS

Depending on your compiler and compiler settings, you might get no or a
lot of warnings when compiling libev code. Some people are apparently
scared by this.

However, these are unavoidable for many reasons. For one, each compiler
has different warnings, and each user has different tastes regarding



( run in 0.573 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )