mirror of /home/gitosis/repositories/libev.git
*** empty log message ***
This commit is contained in:
parent
0ce80fd8f4
commit
cacd28f5a7
62
ev.h
62
ev.h
|
@ -530,43 +530,43 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
|
|||
ev_set_cb ((ev), cb_); \
|
||||
} while (0)
|
||||
|
||||
#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV_IOFDSET; } while (0)
|
||||
#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
|
||||
#define ev_periodic_set(ev,ofs_,ival_,res_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb= (res_); } while (0)
|
||||
#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
|
||||
#define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
|
||||
#define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
|
||||
#define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_check_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0)
|
||||
#define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_async_set(ev) do { (ev)->sent = 0; } while (0)
|
||||
#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV_IOFDSET; } while (0)
|
||||
#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
|
||||
#define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
|
||||
#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
|
||||
#define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
|
||||
#define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
|
||||
#define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_check_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0)
|
||||
#define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_async_set(ev) do { (ev)->sent = 0; } while (0)
|
||||
|
||||
#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
|
||||
#define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
|
||||
#define ev_periodic_init(ev,cb,at,ival,res) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(at),(ival),(res)); } while (0)
|
||||
#define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
|
||||
#define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
|
||||
#define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
|
||||
#define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
|
||||
#define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
|
||||
#define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
|
||||
#define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
|
||||
#define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
|
||||
#define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
|
||||
#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
|
||||
#define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
|
||||
#define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
|
||||
#define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
|
||||
#define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
|
||||
#define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
|
||||
#define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
|
||||
#define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
|
||||
#define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
|
||||
#define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
|
||||
#define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
|
||||
#define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
|
||||
|
||||
#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
|
||||
#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
|
||||
#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
|
||||
#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
|
||||
|
||||
#define ev_priority(ev) ((((ev_watcher *)(void *)(ev))->priority) + 0)
|
||||
#define ev_cb(ev) (ev)->cb /* rw */
|
||||
#define ev_set_priority(ev,pri) ((ev_watcher *)(void *)(ev))->priority = (pri)
|
||||
#define ev_priority(ev) ((((ev_watcher *)(void *)(ev))->priority) + 0)
|
||||
#define ev_cb(ev) (ev)->cb /* rw */
|
||||
#define ev_set_priority(ev,pri) ((ev_watcher *)(void *)(ev))->priority = (pri)
|
||||
|
||||
#define ev_periodic_at(ev) (((ev_watcher_time *)(ev))->at + 0.)
|
||||
#define ev_periodic_at(ev) (((ev_watcher_time *)(ev))->at + 0.)
|
||||
|
||||
#ifndef ev_set_cb
|
||||
# define ev_set_cb(ev,cb_) ev_cb (ev) = (cb_)
|
||||
# define ev_set_cb(ev,cb_) ev_cb (ev) = (cb_)
|
||||
#endif
|
||||
|
||||
/* stopping (enabling, adding) a watcher does nothing if it is already running */
|
||||
|
|
99
ev.pod
99
ev.pod
|
@ -1598,52 +1598,62 @@ inactivity.
|
|||
Periodic watchers are also timers of a kind, but they are very versatile
|
||||
(and unfortunately a bit complex).
|
||||
|
||||
Unlike C<ev_timer>'s, they are not based on real time (or relative time)
|
||||
but on wall clock time (absolute time). You can tell a periodic watcher
|
||||
to trigger after some specific point in time. For example, if you tell a
|
||||
periodic watcher to trigger in 10 seconds (by specifying e.g. C<ev_now ()
|
||||
+ 10.>, that is, an absolute time not a delay) and then reset your system
|
||||
clock to January of the previous year, then it will take more than year
|
||||
to trigger the event (unlike an C<ev_timer>, which would still trigger
|
||||
roughly 10 seconds later as it uses a relative timeout).
|
||||
Unlike C<ev_timer>, periodic watchers are not based on real time (or
|
||||
relative time, the physical time that passes) but on wall clock time
|
||||
(absolute time, the thing you can read on your calender or clock). The
|
||||
difference is that wall clock time can run faster or slower than real
|
||||
time, and time jumps are not uncommon (e.g. when you adjust your
|
||||
wrist-watch).
|
||||
|
||||
C<ev_periodic>s can also be used to implement vastly more complex timers,
|
||||
such as triggering an event on each "midnight, local time", or other
|
||||
complicated rules.
|
||||
You can tell a periodic watcher to trigger after some specific point
|
||||
in time: for example, if you tell a periodic watcher to trigger "in 10
|
||||
seconds" (by specifying e.g. C<ev_now () + 10.>, that is, an absolute time
|
||||
not a delay) and then reset your system clock to January of the previous
|
||||
year, then it will take a year or more to trigger the event (unlike an
|
||||
C<ev_timer>, which would still trigger roughly 10 seconds after starting
|
||||
it, as it uses a relative timeout).
|
||||
|
||||
C<ev_periodic> watchers can also be used to implement vastly more complex
|
||||
timers, such as triggering an event on each "midnight, local time", or
|
||||
other complicated rules. This cannot be done with C<ev_timer> watchers, as
|
||||
those cannot react to time jumps.
|
||||
|
||||
As with timers, the callback is guaranteed to be invoked only when the
|
||||
time (C<at>) has passed, but if multiple periodic timers become ready
|
||||
during the same loop iteration, then order of execution is undefined.
|
||||
point in time where it is supposed to trigger has passed, but if multiple
|
||||
periodic timers become ready during the same loop iteration, then order of
|
||||
execution is undefined.
|
||||
|
||||
=head3 Watcher-Specific Functions and Data Members
|
||||
|
||||
=over 4
|
||||
|
||||
=item ev_periodic_init (ev_periodic *, callback, ev_tstamp at, ev_tstamp interval, reschedule_cb)
|
||||
=item ev_periodic_init (ev_periodic *, callback, ev_tstamp offset, ev_tstamp interval, reschedule_cb)
|
||||
|
||||
=item ev_periodic_set (ev_periodic *, ev_tstamp at, ev_tstamp interval, reschedule_cb)
|
||||
=item ev_periodic_set (ev_periodic *, ev_tstamp offset, ev_tstamp interval, reschedule_cb)
|
||||
|
||||
Lots of arguments, lets sort it out... There are basically three modes of
|
||||
Lots of arguments, let's sort it out... There are basically three modes of
|
||||
operation, and we will explain them from simplest to most complex:
|
||||
|
||||
=over 4
|
||||
|
||||
=item * absolute timer (at = time, interval = reschedule_cb = 0)
|
||||
=item * absolute timer (offset = absolute time, interval = 0, reschedule_cb = 0)
|
||||
|
||||
In this configuration the watcher triggers an event after the wall clock
|
||||
time C<at> has passed. It will not repeat and will not adjust when a time
|
||||
jump occurs, that is, if it is to be run at January 1st 2011 then it will
|
||||
only run when the system clock reaches or surpasses this time.
|
||||
time C<offset> has passed. It will not repeat and will not adjust when a
|
||||
time jump occurs, that is, if it is to be run at January 1st 2011 then it
|
||||
will be stopped and invoked when the system clock reaches or surpasses
|
||||
this point in time.
|
||||
|
||||
=item * repeating interval timer (at = offset, interval > 0, reschedule_cb = 0)
|
||||
=item * repeating interval timer (offset = offset within interval, interval > 0, reschedule_cb = 0)
|
||||
|
||||
In this mode the watcher will always be scheduled to time out at the next
|
||||
C<at + N * interval> time (for some integer N, which can also be negative)
|
||||
and then repeat, regardless of any time jumps.
|
||||
C<offset + N * interval> time (for some integer N, which can also be
|
||||
negative) and then repeat, regardless of any time jumps. The C<offset>
|
||||
argument is merely an offset into the C<interval> periods.
|
||||
|
||||
This can be used to create timers that do not drift with respect to the
|
||||
system clock, for example, here is a C<ev_periodic> that triggers each
|
||||
hour, on the hour:
|
||||
system clock, for example, here is an C<ev_periodic> that triggers each
|
||||
hour, on the hour (with respect to UTC):
|
||||
|
||||
ev_periodic_set (&periodic, 0., 3600., 0);
|
||||
|
||||
|
@ -1654,9 +1664,9 @@ by 3600.
|
|||
|
||||
Another way to think about it (for the mathematically inclined) is that
|
||||
C<ev_periodic> will try to run the callback in this mode at the next possible
|
||||
time where C<time = at (mod interval)>, regardless of any time jumps.
|
||||
time where C<time = offset (mod interval)>, regardless of any time jumps.
|
||||
|
||||
For numerical stability it is preferable that the C<at> value is near
|
||||
For numerical stability it is preferable that the C<offset> value is near
|
||||
C<ev_now ()> (the current time), but there is no range requirement for
|
||||
this value, and in fact is often specified as zero.
|
||||
|
||||
|
@ -1665,15 +1675,16 @@ speed for example), so if C<interval> is very small then timing stability
|
|||
will of course deteriorate. Libev itself tries to be exact to be about one
|
||||
millisecond (if the OS supports it and the machine is fast enough).
|
||||
|
||||
=item * manual reschedule mode (at and interval ignored, reschedule_cb = callback)
|
||||
=item * manual reschedule mode (offset ignored, interval ignored, reschedule_cb = callback)
|
||||
|
||||
In this mode the values for C<interval> and C<at> are both being
|
||||
In this mode the values for C<interval> and C<offset> are both being
|
||||
ignored. Instead, each time the periodic watcher gets scheduled, the
|
||||
reschedule callback will be called with the watcher as first, and the
|
||||
current time as second argument.
|
||||
|
||||
NOTE: I<This callback MUST NOT stop or destroy any periodic watcher,
|
||||
ever, or make ANY other event loop modifications whatsoever>.
|
||||
NOTE: I<This callback MUST NOT stop or destroy any periodic watcher, ever,
|
||||
or make ANY other event loop modifications whatsoever, unless explicitly
|
||||
allowed by documentation here>.
|
||||
|
||||
If you need to stop it, return C<now + 1e30> (or so, fudge fudge) and stop
|
||||
it afterwards (e.g. by starting an C<ev_prepare> watcher, which is the
|
||||
|
@ -1713,13 +1724,16 @@ program when the crontabs have changed).
|
|||
|
||||
=item ev_tstamp ev_periodic_at (ev_periodic *)
|
||||
|
||||
When active, returns the absolute time that the watcher is supposed to
|
||||
trigger next.
|
||||
When active, returns the absolute time that the watcher is supposed
|
||||
to trigger next. This is not the same as the C<offset> argument to
|
||||
C<ev_periodic_set>, but indeed works even in interval and manual
|
||||
rescheduling modes.
|
||||
|
||||
=item ev_tstamp offset [read-write]
|
||||
|
||||
When repeating, this contains the offset value, otherwise this is the
|
||||
absolute point in time (the C<at> value passed to C<ev_periodic_set>).
|
||||
absolute point in time (the C<offset> value passed to C<ev_periodic_set>,
|
||||
although libev might modify this value for better numerical stability).
|
||||
|
||||
Can be modified any time, but changes only take effect when the periodic
|
||||
timer fires or C<ev_periodic_again> is being called.
|
||||
|
@ -2684,9 +2698,14 @@ C<ev_feed_event>, this call is safe to do from other threads, signal or
|
|||
similar contexts (see the discussion of C<EV_ATOMIC_T> in the embedding
|
||||
section below on what exactly this means).
|
||||
|
||||
This call incurs the overhead of a system call only once per loop iteration,
|
||||
so while the overhead might be noticeable, it doesn't apply to repeated
|
||||
calls to C<ev_async_send>.
|
||||
Note that, as with other watchers in libev, multiple events might get
|
||||
compressed into a single callback invocation (another way to look at this
|
||||
is that C<ev_async> watchers are level-triggered, set on C<ev_async_send>,
|
||||
reset when the event loop detects that).
|
||||
|
||||
This call incurs the overhead of a system call only once per event loop
|
||||
iteration, so while the overhead might be noticeable, it doesn't apply to
|
||||
repeated calls to C<ev_async_send> for the same event loop.
|
||||
|
||||
=item bool = ev_async_pending (ev_async *)
|
||||
|
||||
|
@ -2699,8 +2718,10 @@ the loop iterates next and checks for the watcher to have become active,
|
|||
it will reset the flag again. C<ev_async_pending> can be used to very
|
||||
quickly check whether invoking the loop might be a good idea.
|
||||
|
||||
Not that this does I<not> check whether the watcher itself is pending, only
|
||||
whether it has been requested to make this watcher pending.
|
||||
Not that this does I<not> check whether the watcher itself is pending,
|
||||
only whether it has been requested to make this watcher pending: there
|
||||
is a time window between the event loop checking and resetting the async
|
||||
notification, and the callback being invoked.
|
||||
|
||||
=back
|
||||
|
||||
|
|
Loading…
Reference in New Issue