EV
view release on metacpan or search on metacpan
If this callback throws an exception it will be silently ignored.
=item $flags = EV::supported_backends
=item $flags = EV::recommended_backends
=item $flags = EV::embeddable_backends
Returns the set (see C<EV::BACKEND_*> flags) of backends supported by this
instance of EV, the set of recommended backends (supposed to be good) for
this platform and the set of embeddable backends (see EMBED WATCHERS).
=item EV::sleep $seconds
Block the process for the given number of (fractional) seconds.
=item $time = EV::time
Returns the current time in (fractional) seconds since the epoch.
=item $time = EV::now
=item $w = $loop->fork_ns ($callback)
Call the callback before the event loop is resumed in the child process
after a fork.
The C<fork_ns> variant doesn't start (activate) the newly created watcher.
=back
=head3 EMBED WATCHERS - when one backend isn't enough...
This is a rather advanced watcher type that lets you embed one event loop
into another (currently only IO events are supported in the embedded
loop, other types of watchers might be handled in a delayed or incorrect
fashion and must not be used).
See the libev documentation at
L<http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_embed_code_when_one_backend_>
(locally installed as F<EV::libev>) for more details.
const_iv (EV_, WRITE)
const_iv (EV_, IO)
const_iv (EV_, TIMER)
const_iv (EV_, PERIODIC)
const_iv (EV_, SIGNAL)
const_iv (EV_, CHILD)
const_iv (EV_, STAT)
const_iv (EV_, IDLE)
const_iv (EV_, PREPARE)
/*const_iv (EV_, CHECK) needs special tretament */
const_iv (EV_, EMBED)
const_iv (EV_, FORK)
const_iv (EV_, CLEANUP)
const_iv (EV_, ASYNC)
const_iv (EV_, CUSTOM)
const_iv (EV_, ERROR)
const_iv (EV, RUN_NOWAIT)
const_iv (EV, RUN_ONCE)
const_iv (EV, BREAK_CANCEL)
default prints an informative message and continues.
If this callback throws an exception it will be silently ignored.
$flags = EV::supported_backends
$flags = EV::recommended_backends
$flags = EV::embeddable_backends
Returns the set (see "EV::BACKEND_*" flags) of backends supported by
this instance of EV, the set of recommended backends (supposed to be
good) for this platform and the set of embeddable backends (see
EMBED WATCHERS).
EV::sleep $seconds
Block the process for the given number of (fractional) seconds.
$time = EV::time
Returns the current time in (fractional) seconds since the epoch.
$time = EV::now
$time = $loop->now
Returns the time the last event loop iteration has been started.
$w = EV::fork $callback
$w = EV::fork_ns $callback
$w = $loop->fork ($callback)
$w = $loop->fork_ns ($callback)
Call the callback before the event loop is resumed in the child
process after a fork.
The "fork_ns" variant doesn't start (activate) the newly created
watcher.
EMBED WATCHERS - when one backend isn't enough...
This is a rather advanced watcher type that lets you embed one event
loop into another (currently only IO events are supported in the
embedded loop, other types of watchers might be handled in a delayed or
incorrect fashion and must not be used).
See the libev documentation at
<http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_embed_code
_when_one_backend_> (locally installed as EV::libev) for more details.
In short, this watcher is most useful on BSD systems without working
checks [active - 1] = checks [--checkcnt];
ev_active (checks [active - 1]) = active;
}
ev_stop (EV_A_ (W)w);
EV_FREQUENT_CHECK;
}
#endif
#if EV_EMBED_ENABLE
ecb_noinline
void
ev_embed_sweep (EV_P_ ev_embed *w) EV_NOEXCEPT
{
ev_run (w->other, EVRUN_NOWAIT);
}
static void
embed_io_cb (EV_P_ ev_io *io, int revents)
{
ev_embed *w = (ev_embed *)(((char *)io) - offsetof (ev_embed, io));
if (ev_cb (w))
ev_feed_event (EV_A_ (W)w, EV_EMBED);
else
ev_run (w->other, EVRUN_NOWAIT);
}
static void
embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents)
{
ev_embed *w = (ev_embed *)(((char *)prepare) - offsetof (ev_embed, prepare));
{
/*****************************************************************************/
#if EV_WALK_ENABLE
ecb_cold
void
ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_NOEXCEPT
{
int i, j;
ev_watcher_list *wl, *wn;
if (types & (EV_IO | EV_EMBED))
for (i = 0; i < anfdmax; ++i)
for (wl = anfds [i].head; wl; )
{
wn = wl->next;
#if EV_EMBED_ENABLE
if (ev_cb ((ev_io *)wl) == embed_io_cb)
{
if (types & EV_EMBED)
cb (EV_A_ EV_EMBED, ((char *)wl) - offsetof (struct ev_embed, io));
}
else
#endif
#if EV_USE_INOTIFY
if (ev_cb ((ev_io *)wl) == infy_cb)
;
else
#endif
if ((ev_io *)wl != &pipe_w)
if (types & EV_IO)
#if EV_ASYNC_ENABLE
if (types & EV_ASYNC)
for (i = asynccnt; i--; )
cb (EV_A_ EV_ASYNC, asyncs [i]);
#endif
#if EV_PREPARE_ENABLE
if (types & EV_PREPARE)
for (i = preparecnt; i--; )
# if EV_EMBED_ENABLE
if (ev_cb (prepares [i]) != embed_prepare_cb)
# endif
cb (EV_A_ EV_PREPARE, prepares [i]);
#endif
#if EV_CHECK_ENABLE
if (types & EV_CHECK)
for (i = checkcnt; i--; )
cb (EV_A_ EV_CHECK, checks [i]);
#endif
if (types & EV_CHILD)
for (i = (EV_PID_HASHSIZE); i--; )
for (wl = childs [i]; wl; )
{
wn = wl->next;
cb (EV_A_ EV_CHILD, wl);
wl = wn;
}
#endif
/* EV_STAT 0x00001000 /* stat data changed */
/* EV_EMBED 0x00010000 /* embedded event loop needs sweep */
}
#endif
#if EV_MULTIPLICITY
#include "ev_wrap.h"
#endif
# define EV_CHILD_ENABLE 0
# else
# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
#endif
#endif
#ifndef EV_ASYNC_ENABLE
# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_EMBED_ENABLE
# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_WALK_ENABLE
# define EV_WALK_ENABLE 0 /* not yet */
#endif
/*****************************************************************************/
#if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE
# undef EV_SIGNAL_ENABLE
# define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */
#else
# define EV_P void
# define EV_P_
# define EV_A
# define EV_A_
# define EV_DEFAULT
# define EV_DEFAULT_
# define EV_DEFAULT_UC
# define EV_DEFAULT_UC_
# undef EV_EMBED_ENABLE
#endif
/* EV_INLINE is used for functions in header files */
#if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3
# define EV_INLINE static inline
#else
# define EV_INLINE static
#endif
#ifdef EV_API_STATIC
#if EV_COMPAT3
EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */
#endif
EV_PERIODIC = 0x00000200, /* periodic timer timed out */
EV_SIGNAL = 0x00000400, /* signal was received */
EV_CHILD = 0x00000800, /* child/pid had status change */
EV_STAT = 0x00001000, /* stat data changed */
EV_IDLE = 0x00002000, /* event loop is idling */
EV_PREPARE = 0x00004000, /* event loop about to poll */
EV_CHECK = 0x00008000, /* event loop finished poll */
EV_EMBED = 0x00010000, /* embedded event loop needs sweep */
EV_FORK = 0x00020000, /* event loop resumed in child */
EV_CLEANUP = 0x00040000, /* event loop resumed in child */
EV_ASYNC = 0x00080000, /* async intra-loop signal */
EV_CUSTOM = 0x01000000, /* for use by user code */
EV_ERROR = (int)0x80000000 /* sent when an error occurs */
};
/* can be used to add custom fields to all watchers, while losing binary compatibility */
#ifndef EV_COMMON
# define EV_COMMON void *data;
EV_WATCHER (ev_fork)
} ev_fork;
/* is invoked just before the loop gets destroyed */
/* revent EV_CLEANUP */
typedef struct ev_cleanup
{
EV_WATCHER (ev_cleanup)
} ev_cleanup;
#if EV_EMBED_ENABLE
/* used to embed an event loop inside another */
/* the callback gets invoked when the event loop has handled events, and can be 0 */
typedef struct ev_embed
{
EV_WATCHER (ev_embed)
struct ev_loop *other; /* ro */
#undef EV_IO_ENABLE
#define EV_IO_ENABLE 1
ev_io io; /* private */
struct ev_idle idle;
#endif
struct ev_prepare prepare;
struct ev_check check;
#if EV_FORK_ENABLE
struct ev_fork fork;
#endif
#if EV_CLEANUP_ENABLE
struct ev_cleanup cleanup;
#endif
#if EV_EMBED_ENABLE
struct ev_embed embed;
#endif
#if EV_ASYNC_ENABLE
struct ev_async async;
#endif
};
/* flag bits for ev_default_loop and ev_loop_new */
enum {
/* the default */
# if EV_FORK_ENABLE
EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w) EV_NOEXCEPT;
EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w) EV_NOEXCEPT;
# endif
# if EV_CLEANUP_ENABLE
EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_NOEXCEPT;
EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_NOEXCEPT;
# endif
# if EV_EMBED_ENABLE
/* only supported when loop to be embedded is in fact embeddable */
EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w) EV_NOEXCEPT;
EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w) EV_NOEXCEPT;
EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w) EV_NOEXCEPT;
# endif
# if EV_ASYNC_ENABLE
EV_API_DECL void ev_async_start (EV_P_ ev_async *w) EV_NOEXCEPT;
EV_API_DECL void ev_async_stop (EV_P_ ev_async *w) EV_NOEXCEPT;
EV_API_DECL void ev_async_send (EV_P_ ev_async *w) EV_NOEXCEPT;
libev/ev.pod view on Meta::CPAN
It also is quite fast (see this
L<benchmark|http://libev.schmorp.de/bench.html> comparing it to libevent
for example).
=head2 CONVENTIONS
Libev is very configurable. In this manual the default (and most common)
configuration will be described, which supports multiple event loops. For
more info about various configuration options please have a look at
B<EMBED> section in this manual. If libev was configured without support
for multiple event loops, then all functions taking an initial argument of
name C<loop> (which is always of type C<struct ev_loop *>) will not have
this argument.
=head2 TIME REPRESENTATION
Libev represents time as a single floating point number, representing
the (fractional) number of seconds since the (POSIX) epoch (in practice
somewhere near the beginning of 1970, details are complicated, don't
ask). This type is called C<ev_tstamp>, which is what you should use
libev/ev.pod view on Meta::CPAN
for any received events. That means C<ev_prepare> watchers are the last
watchers invoked before the event loop sleeps or polls for new events, and
C<ev_check> 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<ev_prepare> watcher might start an idle watcher to keep C<ev_run> from
blocking).
=item C<EV_EMBED>
The embedded event loop specified in the C<ev_embed> watcher needs attention.
=item C<EV_FORK>
The event loop has been resumed in the child process after fork (see
C<ev_fork>).
=item C<EV_CLEANUP>
libev/ev.pod view on Meta::CPAN
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"
libev/ev.pod view on Meta::CPAN
check_cb (EV_P_ ev_timer *w, int revents)
{
ev_check_stop (EV_A_ w);
}
ev_check check;
ev_check_init (&check, check_cb);
ev_check_start (EV_DEFAULT_ &check);
ev_run (EV_DEFAULT_ 0);
=head1 EMBEDDING
Libev can (and often is) directly embedded into host
applications. Examples of applications that embed it include the Deliantra
Game Server, the EV perl module, the GNU Virtual Private Ethernet (gvpe)
and rxvt-unicode.
The goal is to enable you to just copy the necessary files into your
source directory without having to change even a single line in them, so
you can easily upgrade by simply copying (or having a checked-out copy of
libev somewhere in your source tree).
libev/ev.pod view on Meta::CPAN
to be C<-2> and C<2>, respectively).
When doing priority-based operations, libev usually has to linearly search
all the priorities, so having many of them (hundreds) uses a lot of space
and time, so using the defaults of five priorities (-2 .. +2) is usually
fine.
If your embedding application does not need any priorities, defining these
both to C<0> will save some memory and CPU.
=item EV_PERIODIC_ENABLE, EV_IDLE_ENABLE, EV_EMBED_ENABLE, EV_STAT_ENABLE,
EV_PREPARE_ENABLE, EV_CHECK_ENABLE, EV_FORK_ENABLE, EV_SIGNAL_ENABLE,
EV_ASYNC_ENABLE, EV_CHILD_ENABLE.
If undefined or defined to be C<1> (and the platform supports it), then
the respective watcher type is supported. If defined to be C<0>, then it
is not. Disabling watcher types mainly saves code size.
=item EV_FEATURES
If you need to shave off some kilobytes of code at the expense of some
libev/ev.pod view on Meta::CPAN
At the moment, the C<ev.h> header file provides compatibility definitions
for all changes, so most programs should still compile. The compatibility
layer might be removed in later versions of libev, so better update to the
new API early than late.
=over 4
=item C<EV_COMPAT3> backwards compatibility mechanism
The backward compatibility mechanism can be controlled by
C<EV_COMPAT3>. See L</"PREPROCESSOR SYMBOLS/MACROS"> in the L</EMBEDDING>
section.
=item C<ev_default_destroy> and C<ev_default_fork> have been removed
These calls can be replaced easily by their C<ev_loop_xxx> counterparts:
ev_loop_destroy (EV_DEFAULT_UC);
ev_loop_fork (EV_DEFAULT);
=item function/symbol renames
( run in 1.863 second using v1.01-cache-2.11-cpan-71847e10f99 )