EV

 view release on metacpan or  search on metacpan

libev/ev.pod  view on Meta::CPAN


This mode of operation can be useful together with an C<ev_check> watcher,
to do something on each event loop iteration - for example to balance load
between different connections.

See L</Abusing an ev_check watcher for its side-effect> for a longer
example.

=head3 Watcher-Specific Functions and Data Members

=over 4

=item ev_idle_init (ev_idle *, callback)

Initialises and configures the idle watcher - it has no parameters of any
kind. There is a C<ev_idle_set> macro, but using it is utterly pointless,
believe me.

=back

=head3 Examples

Example: Dynamically allocate an C<ev_idle> watcher, start it, and in the
callback, free it. Also, use no error checking, as usual.

   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.
   }

   ev_idle *idle_watcher = malloc (sizeof (ev_idle));
   ev_idle_init (idle_watcher, idle_cb);
   ev_idle_start (loop, idle_watcher);


=head2 C<ev_prepare> and C<ev_check> - customise your event loop!

Prepare and check watchers are often (but not always) used in pairs:
prepare watchers get invoked before the process blocks and check watchers
afterwards.

You I<must not> call C<ev_run> (or similar functions that enter the
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
loops those other event loops might be in an unusable state until their
C<ev_check> watcher ran (always remind yourself to coexist peacefully with
others).

=head3 Abusing an C<ev_check> watcher for its side-effect

C<ev_check> (and less often also C<ev_prepare>) 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<ev_check> 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<ev_check> watcher will not be invoked.

This is where C<ev_idle> watchers come in handy - all you need is a
single global idle watcher that is active as long as you have one active
C<ev_check> watcher. The C<ev_idle> watcher makes sure the event loop
will not sleep, and the C<ev_check> watcher makes sure a callback gets
invoked. Neither watcher alone can do that.

=head3 Watcher-Specific Functions and Data Members

=over 4

=item ev_prepare_init (ev_prepare *, callback)

=item ev_check_init (ev_check *, callback)

Initialises and configures the prepare or check watcher - they have no
parameters of any kind. There are C<ev_prepare_set> and C<ev_check_set>
macros, but using them is utterly, utterly, utterly and completely
pointless.

=back

=head3 Examples

There are a number of principal ways to embed other event loops or modules
into libev. Here are some ideas on how to include libadns into libev
(there is a Perl module named C<EV::ADNS> that does this, which you could
use as a working example. Another Perl module named C<EV::Glib> embeds a
Glib main context into libev, and finally, C<Glib::EV> embeds EV into the
Glib event loop).

Method 1: Add IO watchers and a timeout watcher in a prepare handler,
and in a check watcher, destroy them and call into libadns. What follows
is pseudo-code only of course. This requires you to either use a low

libev/ev.pod  view on Meta::CPAN


     return 0;
   }

Instead of invoking all pending watchers, the C<l_invoke> callback will
signal the main thread via some unspecified mechanism (signals? pipe
writes? C<Async::Interrupt>?) 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<ev_invoke_pending> 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<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.


=head1 LIBEVENT EMULATION

Libev offers a compatibility emulation layer for libevent. It cannot
emulate the internals of libevent, so here are some usage hints:

=over 4

=item * Only the libevent-1.4.1-beta API is being emulated.

This was the newest libevent version available when libev was implemented,
and is still mostly unchanged in 2010.

=item * Use it by including <event.h>, as usual.

=item * The following members are fully supported: ev_base, ev_callback,
ev_arg, ev_fd, ev_res, ev_events.

=item * Avoid using ev_flags and the EVLIST_*-macros, while it is
maintained by libev, it does not work exactly the same way as in libevent (consider
it a private API).

=item * Priorities are not currently supported. Initialising priorities
will fail and all watchers will have the same priority, even though there
is an ev_pri field.

=item * In libevent, the last base created gets the signals, in libev, the
base that registered the signal gets the signals.

=item * Other members are not supported.

=item * The libev emulation is I<not> ABI compatible to libevent, you need
to use the libev header file and library.

=back

=head1 C++ SUPPORT

=head2 C API

The normal C API should work fine when used from C++: both ev.h and the
libev sources can be compiled as C++. Therefore, code that uses the C API
will work fine.

Proper exception specifications might have to be added to callbacks passed
to libev: exceptions may be thrown only from watcher callbacks, all other
callbacks (allocator, syserr, loop acquire/release and periodic reschedule
callbacks) must not throw exceptions, and might need a C<noexcept>
specification. If you have code that needs to be compiled as both C and

libev/ev.pod  view on Meta::CPAN


All libev functions are reentrant and thread-safe unless explicitly
documented otherwise, but libev implements no locking itself. This means
that you can use as many loops as you want in parallel, as long as there
are no concurrent calls into any libev function with the same loop
parameter (C<ev_default_*> calls have an implicit default loop parameter,
of course): libev guarantees that different event loops share no data
structures that need any locking.

Or to put it differently: calls with different loop parameters can be done
concurrently from multiple threads, calls with the same loop parameter
must be done serially (but can be done from different threads, as long as
only one thread ever is inside a call at any point in time, e.g. by using
a mutex per loop).

Specifically to support threads (and signal handlers), libev implements
so-called C<ev_async> watchers, which allow some limited form of
concurrency on the same event loop, namely waking it up "from the
outside".

If you want to know which design (one loop, locking, or multiple loops
without or something else still) is best for your problem, then I cannot
help you, but here is some generic advice:

=over 4

=item * most applications have a main thread: use the default libev loop
in that thread, or create a separate thread running only the default loop.

This helps integrating other libraries or software modules that use libev
themselves and don't care/know about threading.

=item * one loop per thread is usually a good model.

Doing this is almost never wrong, sometimes a better-performance model
exists, but it is always a good start.

=item * other models exist, such as the leader/follower pattern, where one
loop is handed through multiple threads in a kind of round-robin fashion.

Choosing a model is hard - look around, learn, know that usually you can do
better than you currently do :-)

=item * often you need to talk to some other thread which blocks in the
event loop.

C<ev_async> watchers can be used to wake them up from other threads safely
(or from signal contexts...).

An example use would be to communicate signals or other events that only
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
warning options. "Warn-free" code therefore cannot be a goal except when
targeting a specific compiler and compiler-version.

Another reason is that some compiler warnings require elaborate
workarounds, or other changes to the code that make it less clear and less
maintainable.

And of course, some compiler warnings are just plain stupid, or simply
wrong (because they don't actually warn about the condition their message
seems to warn about). For example, certain older gcc versions had some
warnings that resulted in an extreme number of false positives. These have
been fixed, but some people still insist on making code warn-free with
such buggy versions.

While libev is written to generate as few warnings as possible,
"warn-free" code is not a goal, and it is recommended not to build libev
with any compiler warnings enabled unless you are prepared to cope with
them (e.g. by ignoring them). Remember that warnings are just that:
warnings, not errors, or proof of bugs.


=head2 VALGRIND

Valgrind has a special section here because it is a popular tool that is
highly useful. Unfortunately, valgrind reports are very hard to interpret.

If you think you found a bug (memory leak, uninitialised data access etc.)
in libev, then check twice: If valgrind reports something like:

   ==2274==    definitely lost: 0 bytes in 0 blocks.
   ==2274==      possibly lost: 0 bytes in 0 blocks.
   ==2274==    still reachable: 256 bytes in 1 blocks.

Then there is no memory leak, just as memory accounted to global variables
is not a memleak - the memory is still being referenced, and didn't leak.

Similarly, under some circumstances, valgrind might report kernel bugs
as if it were a bug in libev (e.g. in realloc or in the poll backend,
although an acceptable workaround has been found here), or it might be
confused.

Keep in mind that valgrind is a very good tool, but only a tool. Don't
make it into some kind of religion.

If you are unsure about something, feel free to contact the mailing list
with the full valgrind report and an explanation on why you think this
is a bug in libev (best check the archives, too :). However, don't be
annoyed when you get a brisk "this is no bug" answer and take the chance
of learning how to interpret valgrind properly.



( run in 2.539 seconds using v1.01-cache-2.11-cpan-df04353d9ac )