Browse Source

*** empty log message ***

master
Marc Alexander Lehmann 11 years ago
parent
commit
8b3080a308
  1. 5
      Changes
  2. 40
      ev.c
  3. 50
      ev.h
  4. 240
      ev.pod
  5. 6
      event.c
  6. 6
      event.h

5
Changes

@ -1,12 +1,13 @@
Revision history for libev, a high-performance and full-featured event loop.
TODO: ABI??? API????? Changes???
TODO: include ev_xyz_start in each example?
TODO: section watcher states/lifetime
TODO: ALL ev_xxx_set funtions must be called from ev++ set methods, somehow.
TODO: use enums //TODO: enum?
- "PORTING FROM LIBEV 3.X TO 4.X" (in ev.pod) is recommended reading.
- ev_embed_stop did not correctly stop the watcher (very good
testcase by Vladimir Timofeev).
- ev_run will now always update the current loop time - it errornously
didn't when idle watchers were active, causing timers not to fire.
- fix a bug where a timeout of zero caused the timer not to fire
in the libevent emulation (testcase by Péter Szabó).
- applied win32 fixes by Michael Lenaghan (also James Mansion).

40
ev.c

@ -719,7 +719,7 @@ typedef struct
# define EV_INVOKE_PENDING ev_invoke_pending (EV_A)
#endif
#define EVUNLOOP_RECURSE 0x80
#define EVBREAK_RECURSE 0x80
/*****************************************************************************/
@ -2294,15 +2294,15 @@ time_update (EV_P_ ev_tstamp max_block)
}
void
ev_loop (EV_P_ int flags)
ev_run (EV_P_ int flags)
{
#if EV_FEATURE_API
++loop_depth;
#endif
assert (("libev: ev_loop recursion during release detected", loop_done != EVUNLOOP_RECURSE));
assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE));
loop_done = EVUNLOOP_CANCEL;
loop_done = EVBREAK_CANCEL;
EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */
@ -2355,14 +2355,14 @@ ev_loop (EV_P_ int flags)
ev_tstamp waittime = 0.;
ev_tstamp sleeptime = 0.;
if (expect_true (!(flags & EVLOOP_NONBLOCK || idleall || !activecnt)))
{
/* remember old timestamp for io_blocktime calculation */
ev_tstamp prev_mn_now = mn_now;
/* remember old timestamp for io_blocktime calculation */
ev_tstamp prev_mn_now = mn_now;
/* update time to cancel out callback processing overhead */
time_update (EV_A_ 1e100);
/* update time to cancel out callback processing overhead */
time_update (EV_A_ 1e100);
if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt)))
{
waittime = MAX_BLOCKTIME;
if (timercnt)
@ -2402,9 +2402,9 @@ ev_loop (EV_P_ int flags)
#if EV_FEATURE_API
++loop_count;
#endif
assert ((loop_done = EVUNLOOP_RECURSE, 1)); /* assert for side effect */
assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */
backend_poll (EV_A_ waittime);
assert ((loop_done = EVUNLOOP_CANCEL, 1)); /* assert for side effect */
assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
/* update ev_rt_now, do magic */
time_update (EV_A_ waittime + sleeptime);
@ -2432,11 +2432,11 @@ ev_loop (EV_P_ int flags)
while (expect_true (
activecnt
&& !loop_done
&& !(flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK))
&& !(flags & (EVRUN_ONCE | EVRUN_NOWAIT))
));
if (loop_done == EVUNLOOP_ONE)
loop_done = EVUNLOOP_CANCEL;
if (loop_done == EVBREAK_ONE)
loop_done = EVBREAK_CANCEL;
#if EV_FEATURE_API
--loop_depth;
@ -2444,7 +2444,7 @@ ev_loop (EV_P_ int flags)
}
void
ev_unloop (EV_P_ int how)
ev_break (EV_P_ int how)
{
loop_done = how;
}
@ -3429,7 +3429,7 @@ ev_check_stop (EV_P_ ev_check *w)
void noinline
ev_embed_sweep (EV_P_ ev_embed *w)
{
ev_loop (w->other, EVLOOP_NONBLOCK);
ev_run (w->other, EVRUN_NOWAIT);
}
static void
@ -3440,7 +3440,7 @@ embed_io_cb (EV_P_ ev_io *io, int revents)
if (ev_cb (w))
ev_feed_event (EV_A_ (W)w, EV_EMBED);
else
ev_loop (w->other, EVLOOP_NONBLOCK);
ev_run (w->other, EVRUN_NOWAIT);
}
static void
@ -3454,7 +3454,7 @@ embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents)
while (fdchangecnt)
{
fd_reify (EV_A);
ev_loop (EV_A_ EVLOOP_NONBLOCK);
ev_run (EV_A_ EVRUN_NOWAIT);
}
}
}
@ -3470,7 +3470,7 @@ embed_fork_cb (EV_P_ ev_fork *fork_w, int revents)
EV_P = w->other;
ev_loop_fork (EV_A);
ev_loop (EV_A_ EVLOOP_NONBLOCK);
ev_run (EV_A_ EVRUN_NOWAIT);
}
ev_embed_start (EV_A_ w);

50
ev.h

@ -181,6 +181,7 @@ struct ev_loop;
#define EV_VERSION_MINOR 0
/* eventmask, revents, events... */
//TODO: enum?
#define EV_UNDEF -1 /* guaranteed to be invalid */
#define EV_NONE 0x00 /* no events */
#define EV_READ 0x01 /* ev_io detected read will not block */
@ -443,6 +444,7 @@ union ev_any_watcher
#endif
};
//TODO: enum?
/* bits for ev_default_loop and ev_loop_new */
/* the default */
#define EVFLAG_AUTO 0x00000000U /* not quite a mask */
@ -453,6 +455,7 @@ union ev_any_watcher
#define EVFLAG_NOINOTIFY 0x00100000U /* do not attempt to use inotify */
#define EVFLAG_NOSIGFD 0 /* compatibility to pre-3.9 */
#define EVFLAG_SIGNALFD 0x00200000U /* attempt to use signalfd */
//TODO: enum?
/* method bits to be ored together */
#define EVBACKEND_SELECT 0x00000001U /* about anywhere */
#define EVBACKEND_POLL 0x00000002U /* !win */
@ -565,15 +568,17 @@ void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
#endif /* prototypes */
#define EVLOOP_NONBLOCK 1 /* do not block/wait */
#define EVLOOP_ONESHOT 2 /* block *once* only */
#define EVUNLOOP_CANCEL 0 /* undo unloop */
#define EVUNLOOP_ONE 1 /* unloop once */
#define EVUNLOOP_ALL 2 /* unloop all loops */
//TODO: enum?
#define EVRUN_NOWAIT 1 /* do not block/wait */
#define EVRUN_ONCE 2 /* block *once* only */
#define EVBREAK_CANCEL 0 /* undo unloop */
#define EVBREAK_ONE 1 /* unloop once */
#define EVBREAK_ALL 2 /* unloop all loops */
#if EV_PROTOTYPES
void ev_loop (EV_P_ int flags);
void ev_unloop (EV_P_ int how); /* set to 1 to break out of event loop, set to 2 to break out of all event loops */
void ev_run (EV_P_ int flags);
void ev_break (EV_P_ int how); /* set to 1 to break out of event loop, set to 2 to break out of all event loops */
/*
* ref/unref can be used to add or remove a refcount on the mainloop. every watcher
@ -594,13 +599,6 @@ unsigned int ev_iteration (EV_P); /* number of loop iterations */
unsigned int ev_depth (EV_P); /* #ev_loop enters - #ev_loop leaves */
void ev_verify (EV_P); /* abort if loop data corrupted */
/* pre 4.0 API compatibility */
# if EV_MULTIPLICITY
# define ev_loop_count(l) ev_iteration (l)
# define ev_loop_depth(l) ev_depth (l)
# define ev_loop_verify(l) ev_verify (l)
# endif
void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
@ -757,6 +755,30 @@ void ev_async_stop (EV_P_ ev_async *w);
void ev_async_send (EV_P_ ev_async *w);
# endif
/* pre-4.0 compatibility */
#ifndef EV_COMPAT3
# define EV_COMPAT3 1
#endif
#if EV_COMPAT3
#define EVLOOP_NONBLOCK EVRUN_NOWAIT
#define EVLOOP_ONESHOT EVRUN_ONCE
#define EVUNLOOP_CANCEL EVBREAK_CANCEL
#define EVUNLOOP_ONE EVBREAK_ONE
#define EVUNLOOP_ALL EVBREAK_ALL
#if EV_PROTOTYPES
EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); }
EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); }
#if EV_FEATURE_API
EV_INLINE void ev_loop_count (EV_P) { ev_iteration (EV_A); }
EV_INLINE void ev_loop_depth (EV_P) { ev_depth (EV_A); }
EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); }
#endif
#endif
#else
typedef struct ev_loop ev_loop;
#endif
#endif
#ifdef __cplusplus

240
ev.pod

@ -28,8 +28,8 @@ libev - a high performance full-featured event loop written in C
// with its corresponding stop function.
ev_io_stop (EV_A_ w);
// this causes all nested ev_loop's to stop iterating
ev_unloop (EV_A_ EVUNLOOP_ALL);
// this causes all nested ev_run's to stop iterating
ev_break (EV_A_ EVBREAK_ALL);
}
// another callback, this time for a time-out
@ -37,8 +37,8 @@ libev - a high performance full-featured event loop written in C
timeout_cb (EV_P_ ev_timer *w, int revents)
{
puts ("timeout");
// this causes the innermost ev_loop to stop iterating
ev_unloop (EV_A_ EVUNLOOP_ONE);
// this causes the innermost ev_run to stop iterating
ev_break (EV_A_ EVBREAK_ONE);
}
int
@ -58,7 +58,7 @@ libev - a high performance full-featured event loop written in C
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive
ev_loop (loop, 0);
ev_run (loop, 0);
// unloop was called, so exit
return 0;
@ -294,13 +294,13 @@ Example: This is basically the same thing that libev does internally, too.
=head1 FUNCTIONS CONTROLLING THE EVENT LOOP
An event loop is described by a C<struct ev_loop *> (the C<struct>
is I<not> optional in this case, as there is also an C<ev_loop>
I<function>).
An event loop is described by a C<struct ev_loop *> (the C<struct> is
I<not> optional in case unless libev 3 compatibility is disabled, as libev
3 had an C<ev_loop> function colliding with the struct name).
The library knows two types of such loops, the I<default> loop, which
supports signals and child events, and dynamically created loops which do
not.
supports signals and child events, and dynamically created event loops
which do not.
=over 4
@ -608,12 +608,12 @@ earlier call to C<ev_loop_new>.
=item ev_default_fork ()
This function sets a flag that causes subsequent C<ev_loop> iterations
This function sets a flag that causes subsequent C<ev_run> iterations
to reinitialise the kernel state for backends that have one. Despite the
name, you can call it anytime, but it makes most sense after forking, in
the child process (or both child and parent, but that again makes little
sense). You I<must> call it in the child before using any of the libev
functions, and it will only take effect at the next C<ev_loop> iteration.
functions, and it will only take effect at the next C<ev_run> iteration.
Again, you I<have> to call it on I<any> loop that you want to re-use after
a fork, I<even if you do not plan to use the loop in the parent>. This is
@ -621,9 +621,11 @@ because some kernel interfaces *cough* I<kqueue> *cough* do funny things
during fork.
On the other hand, you only need to call this function in the child
process if and only if you want to use the event loop in the child. If you
just fork+exec or create a new loop in the child, you don't have to call
it at all.
process if and only if you want to use the event loop in the child. If
you just fork+exec or create a new loop in the child, you don't have to
call it at all (in fact, C<epoll> is so badly broken that it makes a
difference, but libev will usually detect this case on its own and do a
costly reset of the backend).
The function itself is quite fast and it's usually not a problem to call
it just in case after a fork. To make this easy, the function will fit in
@ -645,9 +647,9 @@ otherwise.
=item unsigned int ev_iteration (loop)
Returns the current iteration count for the loop, which is identical to
the number of times libev did poll for new events. It starts at C<0> and
happily wraps around with enough iterations.
Returns the current iteration count for the event loop, which is identical
to the number of times libev did poll for new events. It starts at C<0>
and happily wraps around with enough iterations.
This value can sometimes be useful as a generation counter of sorts (it
"ticks" the number of loop iterations), as it roughly corresponds with
@ -656,16 +658,16 @@ prepare and check phases.
=item unsigned int ev_depth (loop)
Returns the number of times C<ev_loop> was entered minus the number of
times C<ev_loop> was exited, in other words, the recursion depth.
Returns the number of times C<ev_run> was entered minus the number of
times C<ev_run> was exited, in other words, the recursion depth.
Outside C<ev_loop>, this number is zero. In a callback, this number is
C<1>, unless C<ev_loop> was invoked recursively (or from another thread),
Outside C<ev_run>, this number is zero. In a callback, this number is
C<1>, unless C<ev_run> was invoked recursively (or from another thread),
in which case it is higher.
Leaving C<ev_loop> abnormally (setjmp/longjmp, cancelling the thread
Leaving C<ev_run> abnormally (setjmp/longjmp, cancelling the thread
etc.), doesn't count as "exit" - consider this as a hint to avoid such
ungentleman behaviour unless it's really convenient.
ungentleman-like behaviour unless it's really convenient.
=item unsigned int ev_backend (loop)
@ -684,7 +686,7 @@ event occurring (or more correctly, libev finding out about it).
Establishes the current time by querying the kernel, updating the time
returned by C<ev_now ()> in the progress. This is a costly operation and
is usually done automatically within C<ev_loop ()>.
is usually done automatically within C<ev_run ()>.
This function is rarely useful, but when some event callback runs for a
very long time without entering the event loop, updating libev's idea of
@ -696,8 +698,8 @@ See also L<The special problem of time updates> in the C<ev_timer> section.
=item ev_resume (loop)
These two functions suspend and resume a loop, for use when the loop is
not used for a while and timeouts should not be processed.
These two functions suspend and resume an event loop, for use when the
loop is not used for a while and timeouts should not be processed.
A typical use case would be an interactive program such as a game: When
the user presses C<^Z> to suspend the game and resumes it an hour later it
@ -718,28 +720,32 @@ without a previous call to C<ev_suspend>.
Calling C<ev_suspend>/C<ev_resume> has the side effect of updating the
event loop time (see C<ev_now_update>).
=item ev_loop (loop, int flags)
=item 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.
handling events. It will ask the operating system for any new events, call
the watcher callbacks, an then repeat the whole process indefinitely: This
is why event loops are called I<loops>.
If the flags argument is specified as C<0>, it will not return until
either no event watchers are active anymore or C<ev_unloop> was called.
If the flags argument is specified as C<0>, it will keep handling events
until either no event watchers are active anymore or C<ev_break> was
called.
Please note that an explicit C<ev_unloop> is usually better than
Please note that an explicit C<ev_break> 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
that automatically loops as long as it has to and no longer by virtue
of relying on its watchers stopping correctly, that is truly a thing of
beauty.
A flags value of C<EVLOOP_NONBLOCK> will look for new events, will handle
those events and any already outstanding ones, but will not block your
process in case there are no events and will return after one iteration of
the loop.
A flags value of C<EVRUN_NOWAIT> will look for new events, will handle
those events and any already outstanding ones, but will not wait and
block your process in case there are no events and will return after one
iteration of the loop. This is sometimes useful to poll and handle new
events while doing lengthy calculations, to keep the program responsive.
A flags value of C<EVLOOP_ONESHOT> will look for new events (waiting if
A flags value of C<EVRUN_ONCE> will look for new events (waiting if
necessary) and will handle those and any already outstanding ones. It
will block your process until at least one new event arrives (which could
be an event internal to libev itself, so there is no guarantee that a
@ -748,55 +754,64 @@ iteration of the loop.
This is useful if you are waiting for some external event in conjunction
with something not expressible using other libev watchers (i.e. "roll your
own C<ev_loop>"). However, a pair of C<ev_prepare>/C<ev_check> watchers is
own C<ev_run>"). However, a pair of C<ev_prepare>/C<ev_check> watchers is
usually a better approach for this kind of thing.
Here are the gory details of what C<ev_loop> does:
Here are the gory details of what C<ev_run> does:
- Increment loop depth.
- Reset the ev_break status.
- Before the first iteration, call any pending watchers.
* If EVFLAG_FORKCHECK was used, check for a fork.
LOOP:
- If EVFLAG_FORKCHECK was used, check for a fork.
- If a fork was detected (by any means), queue and call all fork watchers.
- Queue and call all prepare watchers.
- If ev_break was called, goto FINISH.
- If we have been forked, detach and recreate the kernel state
as to not disturb the other process.
- Update the kernel state with all outstanding changes.
- Update the "event loop time" (ev_now ()).
- Calculate for how long to sleep or block, if at all
(active idle watchers, EVLOOP_NONBLOCK or not having
(active idle watchers, EVRUN_NOWAIT or not having
any active watchers at all will result in not sleeping).
- Sleep if the I/O and timer collect interval say so.
- Increment loop iteration counter.
- Block the process, waiting for any events.
- Queue all outstanding I/O (fd) events.
- Update the "event loop time" (ev_now ()), and do time jump adjustments.
- Queue all expired timers.
- Queue all expired periodics.
- Unless any events are pending now, queue all idle watchers.
- Queue all idle watchers with priority higher than that of pending events.
- Queue all check watchers.
- Call all queued watchers in reverse order (i.e. check watchers first).
Signals and child watchers are implemented as I/O watchers, and will
be handled here by queueing them when their watcher gets executed.
- If ev_unloop has been called, or EVLOOP_ONESHOT or EVLOOP_NONBLOCK
were used, or there are no active watchers, return, otherwise
continue with step *.
- If ev_break has been called, or EVRUN_ONCE or EVRUN_NOWAIT
were used, or there are no active watchers, goto FINISH, otherwise
continue with step LOOP.
FINISH:
- Reset the ev_break status iff it was EVBREAK_ONE.
- Decrement the loop depth.
- Return.
Example: Queue some jobs and then loop until no events are outstanding
anymore.
... 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_loop (my_loop, 0);
ev_run (my_loop, 0);
... jobs done or somebody called unloop. yeah!
=item ev_unloop (loop, how)
=item ev_break (loop, how)
Can be used to make a call to C<ev_loop> return early (but only after it
Can be used to make a call to C<ev_run> return early (but only after it
has processed all outstanding events). The C<how> argument must be either
C<EVUNLOOP_ONE>, which will make the innermost C<ev_loop> call return, or
C<EVUNLOOP_ALL>, which will make all nested C<ev_loop> calls return.
C<EVBREAK_ONE>, which will make the innermost C<ev_run> call return, or
C<EVBREAK_ALL>, which will make all nested C<ev_run> calls return.
This "unloop state" will be cleared when entering C<ev_loop> again.
This "unloop state" will be cleared when entering C<ev_run> again.
It is safe to call C<ev_unloop> from outside any C<ev_loop> calls.
It is safe to call C<ev_break> from outside any C<ev_run> calls. ##TODO##
=item ev_ref (loop)
@ -804,15 +819,15 @@ It is safe to call C<ev_unloop> from outside any C<ev_loop> calls.
Ref/unref can be used to add or remove a reference count on the event
loop: Every watcher keeps one reference, and as long as the reference
count is nonzero, C<ev_loop> will not return on its own.
count is nonzero, C<ev_run> will not return on its own.
This is useful when you have a watcher that you never intend to
unregister, but that nevertheless should not keep C<ev_loop> from
unregister, but that nevertheless should not keep C<ev_run> from
returning. In such a case, call C<ev_unref> after starting, and C<ev_ref>
before stopping it.
As an example, libev itself uses this for its internal signal pipe: It
is not visible to the libev user and should not keep C<ev_loop> from
is not visible to the libev user and should not keep C<ev_run> from
exiting if no event watchers registered by it are active. It is also an
excellent way to do this for generic recurring timers or from within
third-party libraries. Just remember to I<unref after start> and I<ref
@ -821,7 +836,7 @@ before, respectively. Note also that libev might stop watchers itself
(e.g. non-repeating timers) in which case you have to C<ev_ref>
in the callback).
Example: Create a signal watcher, but keep it from keeping C<ev_loop>
Example: Create a signal watcher, but keep it from keeping C<ev_run>
running when nothing else is active.
ev_signal exitsig;
@ -894,7 +909,7 @@ more often than 100 times per second:
=item ev_invoke_pending (loop)
This call will simply invoke all pending watchers while resetting their
pending state. Normally, C<ev_loop> does this automatically when required,
pending state. Normally, C<ev_run> does this automatically when required,
but when overriding the invoke callback this call comes handy.
=item int ev_pending_count (loop)
@ -905,7 +920,7 @@ are pending.
=item ev_set_invoke_pending_cb (loop, void (*invoke_pending_cb)(EV_P))
This overrides the invoke pending functionality of the loop: Instead of
invoking all pending watchers when there are any, C<ev_loop> will call
invoking all pending watchers when there are any, C<ev_run> will call
this callback instead. This is useful, for example, when you want to
invoke the actual watchers inside another context (another thread etc.).
@ -918,10 +933,10 @@ Sometimes you want to share the same loop between multiple threads. This
can be done relatively simply by putting mutex_lock/unlock calls around
each call to a libev function.
However, C<ev_loop> 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 loop via
C<ev_unloop> and C<av_async_send>, another way is to set these I<release>
and I<acquire> callbacks on the loop.
However, C<ev_run> 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<ev_break> and C<av_async_send>, another way is to set these
I<release> and I<acquire> callbacks on the loop.
When set, then C<release> will be called just before the thread is
suspended waiting for new events, and C<acquire> is called just
@ -934,10 +949,10 @@ While event loop modifications are allowed between invocations of
C<release> and C<acquire> (that's their only purpose after all), no
modifications done will affect the event loop, i.e. adding watchers will
have no effect on the set of file descriptors being watched, or the time
waited. Use an C<ev_async> watcher to wake up C<ev_loop> when you want it
waited. Use an C<ev_async> watcher to wake up C<ev_run> when you want it
to take note of any changes you made.
In theory, threads executing C<ev_loop> will be async-cancel safe between
In theory, threads executing C<ev_run> will be async-cancel safe between
invocations of C<release> and C<acquire>.
See also the locking example in the C<THREADS> section later in this
@ -984,7 +999,7 @@ become readable, you would create an C<ev_io> watcher for that:
static void my_cb (struct ev_loop *loop, ev_io *w, int revents)
{
ev_io_stop (w);
ev_unloop (loop, EVUNLOOP_ALL);
ev_break (loop, EVBREAK_ALL);
}
struct ev_loop *loop = ev_default_loop (0);
@ -995,7 +1010,7 @@ become readable, you would create an C<ev_io> watcher for that:
ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ);
ev_io_start (loop, &stdin_watcher);
ev_loop (loop, 0);
ev_run (loop, 0);
As you can see, you are responsible for allocating the memory for your
watcher structures (and it is I<usually> a bad idea to do this on the
@ -1069,13 +1084,13 @@ The C<ev_idle> watcher has determined that you have nothing better to do.
=item C<EV_CHECK>
All C<ev_prepare> watchers are invoked just I<before> C<ev_loop> starts
All C<ev_prepare> watchers are invoked just I<before> C<ev_run> starts
to gather new events, and all C<ev_check> watchers are invoked just after
C<ev_loop> has gathered them, but before it invokes any callbacks for any
C<ev_run> 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<ev_prepare> watcher might start an idle watcher to keep
C<ev_loop> from blocking).
C<ev_run> from blocking).
=item C<EV_EMBED>
@ -1626,7 +1641,7 @@ attempt to read a whole line in the callback.
ev_io stdin_readable;
ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ);
ev_io_start (loop, &stdin_readable);
ev_loop (loop, 0);
ev_run (loop, 0);
=head2 C<ev_timer> - relative and optionally repeating timeouts
@ -1645,7 +1660,7 @@ passed (not I<at>, 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<ev_loop> recursively).
no longer true when a callback calls C<ev_run> recursively).
=head3 Be smart about timeouts
@ -1826,7 +1841,7 @@ overkill :)
Establishing the current time is a costly operation (it usually takes at
least two system calls): EV therefore updates its idea of the current
time only before and after C<ev_loop> collects new events, which causes a
time only before and after C<ev_run> collects new events, which causes a
growing difference between C<ev_now ()> and C<ev_time ()> when handling
lots of events in one iteration.
@ -1953,7 +1968,7 @@ inactivity.
ev_timer mytimer;
ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */
ev_timer_again (&mytimer); /* start timer */
ev_loop (loop, 0);
ev_run (loop, 0);
// and in some piece of code that gets executed on any "activity":
// reset the timeout to start ticking again at 10 seconds
@ -1989,7 +2004,7 @@ As with timers, the callback is guaranteed to be invoked only when the
point in time where it is supposed to trigger has passed. If multiple
timers become ready during the same loop iteration then the ones with
earlier time-out values are invoked before ones with later time-out values
(but this is no longer true when a callback calls C<ev_loop> recursively).
(but this is no longer true when a callback calls C<ev_run> recursively).
=head3 Watcher-Specific Functions and Data Members
@ -2237,7 +2252,7 @@ Example: Try to exit cleanly on SIGINT.
static void
sigint_cb (struct ev_loop *loop, ev_signal *w, int revents)
{
ev_unloop (loop, EVUNLOOP_ALL);
ev_break (loop, EVBREAK_ALL);
}
ev_signal signal_watcher;
@ -2633,7 +2648,7 @@ Prepare and check watchers are usually (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_loop> or similar functions that enter
You I<must not> call C<ev_run> or similar functions that enter
the current event loop 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
@ -2811,7 +2826,7 @@ libglib event loop.
// create/start timer
// poll
ev_loop (EV_A_ 0);
ev_run (EV_A_ 0);
// stop timer again
if (timeout >= 0)
@ -2899,7 +2914,7 @@ if you do not want that, you need to temporarily stop the embed watcher).
=item ev_embed_sweep (loop, ev_embed *)
Make a single, non-blocking sweep over the embedded loop. This works
similarly to C<ev_loop (embedded_loop, EVLOOP_NONBLOCK)>, but in the most
similarly to C<ev_run (embedded_loop, EVRUN_NOWAIT)>, but in the most
appropriate way for embedded loops.
=item struct ev_loop *other [read-only]
@ -3015,7 +3030,7 @@ believe me.
=head2 C<ev_async> - how to wake up an event loop
In general, you cannot use an C<ev_loop> from multiple threads or other
In general, you cannot use an C<ev_run> 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).
@ -3532,7 +3547,7 @@ C<EV_A_> is used when other arguments are following. Example:
ev_unref (EV_A);
ev_timer_add (EV_A_ watcher);
ev_loop (EV_A_ 0);
ev_run (EV_A_ 0);
It assumes the variable C<loop> of type C<struct ev_loop *> is in scope,
which is often provided by the following macro.
@ -3582,7 +3597,7 @@ or not.
ev_check check;
ev_check_init (&check, check_cb);
ev_check_start (EV_DEFAULT_ &check);
ev_loop (EV_DEFAULT_ 0);
ev_run (EV_DEFAULT_ 0);
=head1 EMBEDDING
@ -3684,6 +3699,22 @@ settings.
=over 4
=item EV_COMPAT3 (h)
Backwards compatibility is a major concern for libev. This is why this
release of libev comes with wrappers for the functions and symbols that
have been renamed between libev version 3 and 4.
You can disable these wrappers (to test compatibility with future
versions) by defining C<EV_COMPAT3> to C<0> when compiling your
sources. This has the additional advantage that you can drop the C<struct>
from C<struct ev_loop> declarations, as libev will provide an C<ev_loop>
typedef in that case.
In some future version, the default for C<EV_COMPAT3> will become C<0>,
and in some even more future version the compatibility code will be
removed completely.
=item EV_STANDALONE (h)
Must always be C<1> if you do not use autoconf configuration, which
@ -4267,7 +4298,7 @@ protecting the loop data, respectively.
}
The event loop thread first acquires the mutex, and then jumps straight
into C<ev_loop>:
into C<ev_run>:
void *
l_run (void *thr_arg)
@ -4276,7 +4307,7 @@ into C<ev_loop>:
l_acquire (EV_A);
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
ev_loop (EV_A_ 0);
ev_run (EV_A_ 0);
l_release (EV_A);
return 0;
@ -4338,13 +4369,13 @@ watchers in the next event loop iteration.
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_loop> on the same loop from two
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_loop>, and other calls do not usually allow for coroutine switches as
C<ev_run>, and other calls do not usually allow for coroutine switches as
they do not call any callbacks.
=head2 COMPILER WARNINGS
@ -4731,25 +4762,38 @@ removed in later versions of libev, so better update early than late.
=over 4
=item C<ev_loop_count> renamed to C<ev_iteration>
=item function/symbol renames
=item C<ev_loop_depth> renamed to C<ev_depth>
A number of functions and symbols have been renamed:
=item C<ev_loop_verify> renamed to C<ev_verify>
ev_loop => ev_run
EVLOOP_NONBLOCK => EVRUN_NOWAIT
EVLOOP_ONESHOT => EVRUN_ONCE
Most functions working on C<struct ev_loop> objects don't have an
C<ev_loop_> prefix, so it was removed. Note that C<ev_loop_fork> is
still called C<ev_loop_fork> because it would otherwise clash with the
C<ev_fork> typedef.
ev_unloop => ev_break
EVUNLOOP_CANCEL => EVBREAK_CANCEL
EVUNLOOP_ONE => EVBREAK_ONE
EVUNLOOP_ALL => EVBREAK_ALL
=item C<EV_TIMEOUT> renamed to C<EV_TIMER> in C<revents>
EV_TIMEOUT => EV_TIMER
This is a simple rename - all other watcher types use their name
as revents flag, and now C<ev_timer> does, too.
ev_loop_count => ev_iteration
ev_loop_depth => ev_depth
ev_loop_verify => ev_verify
Both C<EV_TIMER> and C<EV_TIMEOUT> symbols were present in 3.x versions
and continue to be present for the foreseeable future, so this is mostly a
documentation change.
Most functions working on C<struct ev_loop> objects don't have an
C<ev_loop_> prefix, so it was removed; C<ev_loop>, C<ev_unloop> and
associated constants have been renamed to not collide with the C<struct
ev_loop> anymore and C<EV_TIMER> now follows the same naming scheme
as all other watcher types. Note that C<ev_loop_fork> is still called
C<ev_loop_fork> because it would otherwise clash with the C<ev_fork>
typedef.
=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_MINIMAL> mechanism replaced by C<EV_FEATURES>

6
event.c

@ -140,7 +140,7 @@ int event_loopexit (struct timeval *tv)
static void
ev_x_cb (struct event *ev, int revents)
{
revents &= EV_READ | EV_WRITE | EV_TIMEOUT | EV_SIGNAL;
revents &= EV_READ | EV_WRITE | EV_TIMER | EV_SIGNAL;
ev->ev_res = revents;
ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg);
@ -327,7 +327,7 @@ int event_base_loop (struct event_base *base, int flags)
{
dLOOPbase;
ev_loop (EV_A_ flags);
ev_run (EV_A_ flags);
return 0;
}
@ -342,7 +342,7 @@ ev_x_loopexit_cb (int revents, void *base)
{
dLOOPbase;
ev_unloop (EV_A_ EVUNLOOP_ONE);
ev_break (EV_A_ EVBREAK_ONE);
}
int event_base_loopexit (struct event_base *base, struct timeval *tv)

6
event.h

@ -46,6 +46,12 @@
# include "ev.h"
#endif
#ifndef EVLOOP_NONBLOCK
# define EVLOOP_NONBLOCK EVRUN_NOWAIT
#endif
#ifndef EVLOOP_ONESHOT
# define EVLOOP_ONESHOT EVRUN_ONCE
#endif
#ifndef EV_TIMEOUT
# define EV_TIMEOUT EV_TIMER
#endif

Loading…
Cancel
Save