mirror of /home/gitosis/repositories/libev.git
*** empty log message ***
parent
a8904a390a
commit
8b3080a308
5
Changes
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).
|
||||
|
|
42
ev.c
42
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;
|
||||
|
||||
/* update time to cancel out callback processing overhead */
|
||||
time_update (EV_A_ 1e100);
|
||||
|
||||
if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt)))
|
||||
{
|
||||
/* 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);
|
||||
|
||||
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
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
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
|
||||
|
||||
ev_unloop => ev_break
|
||||
EVUNLOOP_CANCEL => EVBREAK_CANCEL
|
||||
EVUNLOOP_ONE => EVBREAK_ONE
|
||||
EVUNLOOP_ALL => EVBREAK_ALL
|
||||
|
||||
EV_TIMEOUT => EV_TIMER
|
||||
|
||||
ev_loop_count => ev_iteration
|
||||
ev_loop_depth => ev_depth
|
||||
ev_loop_verify => ev_verify
|
||||
|
||||
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.
|
||||
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_TIMEOUT> renamed to C<EV_TIMER> in C<revents>
|
||||
=item C<EV_COMPAT3> backwards compatibility mechanism
|
||||
|
||||
This is a simple rename - all other watcher types use their name
|
||||
as revents flag, and now C<ev_timer> does, too.
|
||||
|
||||
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.
|
||||
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
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)
|
||||
|
|
Loading…
Reference in New Issue