mirror of /home/gitosis/repositories/libev.git
*** empty log message ***
parent
67ffe0b273
commit
9d22d620d3
109
ev.c
109
ev.c
|
@ -243,9 +243,9 @@ extern "C" {
|
|||
#define expect_true(expr) expect ((expr) != 0, 1)
|
||||
|
||||
#define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
|
||||
#define ABSPRI(w) ((w)->priority - EV_MINPRI)
|
||||
#define ABSPRI(w) (((W)w)->priority - EV_MINPRI)
|
||||
|
||||
#define EMPTY0 /* required for microsofts broken pseudo-c compiler */
|
||||
#define EMPTY /* required for microsofts broken pseudo-c compiler */
|
||||
#define EMPTY2(a,b) /* used to suppress some warnings */
|
||||
|
||||
typedef ev_watcher *W;
|
||||
|
@ -788,9 +788,9 @@ child_reap (EV_P_ ev_signal *sw, int chain, int pid, int status)
|
|||
for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next)
|
||||
if (w->pid == pid || !w->pid)
|
||||
{
|
||||
ev_priority (w) = ev_priority (sw); /* need to do it *now* */
|
||||
w->rpid = pid;
|
||||
w->rstatus = status;
|
||||
ev_set_priority (w, ev_priority (sw)); /* need to do it *now* */
|
||||
w->rpid = pid;
|
||||
w->rstatus = status;
|
||||
ev_feed_event (EV_A_ (W)w, EV_CHILD);
|
||||
}
|
||||
}
|
||||
|
@ -1005,17 +1005,21 @@ loop_destroy (EV_P)
|
|||
#endif
|
||||
|
||||
for (i = NUMPRI; i--; )
|
||||
array_free (pending, [i]);
|
||||
{
|
||||
array_free (pending, [i]);
|
||||
#if EV_IDLE_ENABLE
|
||||
array_free (idle, [i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* have to use the microsoft-never-gets-it-right macro */
|
||||
array_free (fdchange, EMPTY0);
|
||||
array_free (timer, EMPTY0);
|
||||
array_free (fdchange, EMPTY);
|
||||
array_free (timer, EMPTY);
|
||||
#if EV_PERIODIC_ENABLE
|
||||
array_free (periodic, EMPTY0);
|
||||
array_free (periodic, EMPTY);
|
||||
#endif
|
||||
array_free (idle, EMPTY0);
|
||||
array_free (prepare, EMPTY0);
|
||||
array_free (check, EMPTY0);
|
||||
array_free (prepare, EMPTY);
|
||||
array_free (check, EMPTY);
|
||||
|
||||
backend = 0;
|
||||
}
|
||||
|
@ -1161,18 +1165,6 @@ ev_default_fork (void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
int inline_size
|
||||
any_pending (EV_P)
|
||||
{
|
||||
int pri;
|
||||
|
||||
for (pri = NUMPRI; pri--; )
|
||||
if (pendingcnt [pri])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inline_speed
|
||||
call_pending (EV_P)
|
||||
{
|
||||
|
@ -1272,6 +1264,29 @@ periodics_reschedule (EV_P)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if EV_IDLE_ENABLE
|
||||
void inline_size
|
||||
idle_reify (EV_P)
|
||||
{
|
||||
if (expect_false (!idleall))
|
||||
{
|
||||
int pri;
|
||||
|
||||
for (pri = NUMPRI; pri--; )
|
||||
{
|
||||
if (pendingcnt [pri])
|
||||
break;
|
||||
|
||||
if (idlecnt [pri])
|
||||
{
|
||||
queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int inline_size
|
||||
time_update_monotonic (EV_P)
|
||||
{
|
||||
|
@ -1414,7 +1429,7 @@ ev_loop (EV_P_ int flags)
|
|||
{
|
||||
ev_tstamp block;
|
||||
|
||||
if (expect_false (flags & EVLOOP_NONBLOCK || idlecnt || !activecnt))
|
||||
if (expect_false (flags & EVLOOP_NONBLOCK || idleall || !activecnt))
|
||||
block = 0.; /* do not block at all */
|
||||
else
|
||||
{
|
||||
|
@ -1461,9 +1476,10 @@ ev_loop (EV_P_ int flags)
|
|||
periodics_reify (EV_A); /* absolute timers called first */
|
||||
#endif
|
||||
|
||||
#if EV_IDLE_ENABLE
|
||||
/* queue idle watchers unless other events are pending */
|
||||
if (idlecnt && !any_pending (EV_A))
|
||||
queue_events (EV_A_ (W *)idles, idlecnt, EV_IDLE);
|
||||
idle_reify (EV_A);
|
||||
#endif
|
||||
|
||||
/* queue check watchers, to be executed first */
|
||||
if (expect_false (checkcnt))
|
||||
|
@ -1518,12 +1534,19 @@ ev_clear_pending (EV_P_ W w)
|
|||
}
|
||||
}
|
||||
|
||||
void inline_size
|
||||
pri_adjust (EV_P_ W w)
|
||||
{
|
||||
int pri = w->priority;
|
||||
pri = pri < EV_MINPRI ? EV_MINPRI : pri;
|
||||
pri = pri > EV_MAXPRI ? EV_MAXPRI : pri;
|
||||
w->priority = pri;
|
||||
}
|
||||
|
||||
void inline_speed
|
||||
ev_start (EV_P_ W w, int active)
|
||||
{
|
||||
if (w->priority < EV_MINPRI) w->priority = EV_MINPRI;
|
||||
if (w->priority > EV_MAXPRI) w->priority = EV_MAXPRI;
|
||||
|
||||
pri_adjust (EV_A_ w);
|
||||
w->active = active;
|
||||
ev_ref (EV_A);
|
||||
}
|
||||
|
@ -2008,15 +2031,24 @@ ev_stat_stop (EV_P_ ev_stat *w)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if EV_IDLE_ENABLE
|
||||
void
|
||||
ev_idle_start (EV_P_ ev_idle *w)
|
||||
{
|
||||
if (expect_false (ev_is_active (w)))
|
||||
return;
|
||||
|
||||
ev_start (EV_A_ (W)w, ++idlecnt);
|
||||
array_needsize (ev_idle *, idles, idlemax, idlecnt, EMPTY2);
|
||||
idles [idlecnt - 1] = w;
|
||||
pri_adjust (EV_A_ (W)w);
|
||||
|
||||
{
|
||||
int active = ++idlecnt [ABSPRI (w)];
|
||||
|
||||
++idleall;
|
||||
ev_start (EV_A_ (W)w, active);
|
||||
|
||||
array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, EMPTY2);
|
||||
idles [ABSPRI (w)][active - 1] = w;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2028,12 +2060,15 @@ ev_idle_stop (EV_P_ ev_idle *w)
|
|||
|
||||
{
|
||||
int active = ((W)w)->active;
|
||||
idles [active - 1] = idles [--idlecnt];
|
||||
((W)idles [active - 1])->active = active;
|
||||
}
|
||||
|
||||
ev_stop (EV_A_ (W)w);
|
||||
idles [ABSPRI (w)][active - 1] = idles [ABSPRI (w)][--idlecnt [ABSPRI (w)]];
|
||||
((W)idles [ABSPRI (w)][active - 1])->active = active;
|
||||
|
||||
ev_stop (EV_A_ (W)w);
|
||||
--idleall;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ev_prepare_start (EV_P_ ev_prepare *w)
|
||||
|
|
18
ev.h
18
ev.h
|
@ -56,6 +56,10 @@ typedef double ev_tstamp;
|
|||
# define EV_STAT_ENABLE 1
|
||||
#endif
|
||||
|
||||
#ifndef EV_IDLE_ENABLE
|
||||
# define EV_IDLE_ENABLE 1
|
||||
#endif
|
||||
|
||||
#ifndef EV_FORK_ENABLE
|
||||
# define EV_FORK_ENABLE 1
|
||||
#endif
|
||||
|
@ -240,12 +244,14 @@ typedef struct ev_stat
|
|||
} ev_stat;
|
||||
#endif
|
||||
|
||||
#if EV_IDLE_ENABLE
|
||||
/* invoked when the nothing else needs to be done, keeps the process from blocking */
|
||||
/* revent EV_IDLE */
|
||||
typedef struct ev_idle
|
||||
{
|
||||
EV_WATCHER (ev_idle)
|
||||
} ev_idle;
|
||||
#endif
|
||||
|
||||
/* invoked for each run of the mainloop, just before the blocking call */
|
||||
/* you can still change events in any way you like */
|
||||
|
@ -296,7 +302,9 @@ union ev_any_watcher
|
|||
#if EV_STAT_ENABLE
|
||||
struct ev_stat stat;
|
||||
#endif
|
||||
#if EV_IDLE_ENABLE
|
||||
struct ev_idle idle;
|
||||
#endif
|
||||
struct ev_prepare prepare;
|
||||
struct ev_check check;
|
||||
#if EV_FORK_ENABLE
|
||||
|
@ -416,11 +424,11 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
|
|||
|
||||
/* these may evaluate ev multiple times, and the other arguments at most once */
|
||||
/* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
|
||||
#define ev_init(ev,cb_) do { \
|
||||
#define ev_init(ev,cb_) do { \
|
||||
((ev_watcher *)(void *)(ev))->active = \
|
||||
((ev_watcher *)(void *)(ev))->pending = \
|
||||
((ev_watcher *)(void *)(ev))->priority = 0; \
|
||||
ev_set_cb ((ev), cb_); \
|
||||
ev_set_cb ((ev), cb_); \
|
||||
} while (0)
|
||||
|
||||
#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_); } while (0)
|
||||
|
@ -450,9 +458,9 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
|
|||
#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 /* rw */
|
||||
#define ev_priority(ev) ((((ev_watcher *)(void *)(ev))->priority) + 0)
|
||||
#define ev_cb(ev) (ev)->cb /* rw */
|
||||
#define ev_set_priority(ev,pri) ev_priority (ev) = (pri)
|
||||
#define ev_set_priority(ev,pri) ((ev_watcher *)(void *)(ev))->priority = (pri)
|
||||
|
||||
#ifndef ev_set_cb
|
||||
# define ev_set_cb(ev,cb_) ev_cb (ev) = (cb_)
|
||||
|
@ -496,8 +504,10 @@ void ev_stat_stop (EV_P_ ev_stat *w);
|
|||
void ev_stat_stat (EV_P_ ev_stat *w);
|
||||
# endif
|
||||
|
||||
# if EV_IDLE_ENABLE
|
||||
void ev_idle_start (EV_P_ ev_idle *w);
|
||||
void ev_idle_stop (EV_P_ ev_idle *w);
|
||||
# endif
|
||||
|
||||
void ev_prepare_start (EV_P_ ev_prepare *w);
|
||||
void ev_prepare_stop (EV_P_ ev_prepare *w);
|
||||
|
|
48
ev.pod
48
ev.pod
|
@ -746,6 +746,31 @@ Returns the callback currently set on the watcher.
|
|||
Change the callback. You can change the callback at virtually any time
|
||||
(modulo threads).
|
||||
|
||||
=item ev_set_priority (ev_TYPE *watcher, priority)
|
||||
|
||||
=item int ev_priority (ev_TYPE *watcher)
|
||||
|
||||
Set and query the priority of the watcher. The priority is a small
|
||||
integer between C<EV_MAXPRI> (default: C<2>) and C<EV_MINPRI>
|
||||
(default: C<-2>). Pending watchers with higher priority will be invoked
|
||||
before watchers with lower priority, but priority will not keep watchers
|
||||
from being executed (except for C<ev_idle> watchers).
|
||||
|
||||
This means that priorities are I<only> used for ordering callback
|
||||
invocation after new events have been received. This is useful, for
|
||||
example, to reduce latency after idling, or more often, to bind two
|
||||
watchers on the same event and make sure one is called first.
|
||||
|
||||
If you need to suppress invocation when higher priority events are pending
|
||||
you need to look at C<ev_idle> watchers, which provide this functionality.
|
||||
|
||||
The default priority used by watchers when no priority has been set is
|
||||
always C<0>, which is supposed to not be too high and not be too low :).
|
||||
|
||||
Setting a priority outside the range of C<EV_MINPRI> to C<EV_MAXPRI> is
|
||||
fine, as long as you do not mind that the priority value you query might
|
||||
or might not have been adjusted to be within valid range.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
@ -1353,13 +1378,16 @@ Example: Watch C</etc/passwd> for attribute changes.
|
|||
|
||||
=head2 C<ev_idle> - when you've got nothing better to do...
|
||||
|
||||
Idle watchers trigger events when there are no other events are pending
|
||||
(prepare, check and other idle watchers do not count). That is, as long
|
||||
as your process is busy handling sockets or timeouts (or even signals,
|
||||
imagine) it will not be triggered. But when your process is idle all idle
|
||||
watchers are being called again and again, once per event loop iteration -
|
||||
until stopped, that is, or your process receives more events and becomes
|
||||
busy.
|
||||
Idle watchers trigger events when no other events of the same or higher
|
||||
priority are pending (prepare, check and other idle watchers do not
|
||||
count).
|
||||
|
||||
That is, as long as your process is busy handling sockets or timeouts
|
||||
(or even signals, imagine) of the same or higher priority it will not be
|
||||
triggered. But when your process is idle (or only lower-priority watchers
|
||||
are pending), the idle watchers are being called once per event loop
|
||||
iteration - until stopped, that is, or your process receives more events
|
||||
and becomes busy again with higher priority stuff.
|
||||
|
||||
The most noteworthy effect is that as long as any idle watchers are
|
||||
active, the process will not block when waiting for new events.
|
||||
|
@ -2103,6 +2131,12 @@ If undefined or defined to be C<1>, then periodic timers are supported. If
|
|||
defined to be C<0>, then they are not. Disabling them saves a few kB of
|
||||
code.
|
||||
|
||||
=item EV_IDLE_ENABLE
|
||||
|
||||
If undefined or defined to be C<1>, then idle watchers are supported. If
|
||||
defined to be C<0>, then they are not. Disabling them saves a few kB of
|
||||
code.
|
||||
|
||||
=item EV_EMBED_ENABLE
|
||||
|
||||
If undefined or defined to be C<1>, then embed watchers are supported. If
|
||||
|
|
|
@ -73,9 +73,12 @@ VARx(int, periodicmax)
|
|||
VARx(int, periodiccnt)
|
||||
#endif
|
||||
|
||||
VARx(struct ev_idle **, idles)
|
||||
VARx(int, idlemax)
|
||||
VARx(int, idlecnt)
|
||||
#if EV_IDLE_ENABLE || EV_GENWRAP
|
||||
VAR (idles, ev_idle **idles [NUMPRI])
|
||||
VAR (idlemax, int idlemax [NUMPRI])
|
||||
VAR (idlecnt, int idlecnt [NUMPRI])
|
||||
#endif
|
||||
VARx(int, idleall) /* total number */
|
||||
|
||||
VARx(struct ev_prepare **, prepares)
|
||||
VARx(int, preparemax)
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#define idles ((loop)->idles)
|
||||
#define idlemax ((loop)->idlemax)
|
||||
#define idlecnt ((loop)->idlecnt)
|
||||
#define idleall ((loop)->idleall)
|
||||
#define prepares ((loop)->prepares)
|
||||
#define preparemax ((loop)->preparemax)
|
||||
#define preparecnt ((loop)->preparecnt)
|
||||
|
|
|
@ -81,8 +81,8 @@ perl -ne '
|
|||
s/\bevent-internal.h\b//g;
|
||||
s/\bevsignal.h\b//g;
|
||||
s/^(man_MANS\s*=)/$1 ev.3 /;
|
||||
s/^(EXTRA_DIST\s*=)/$1 libev.m4 ev.h ev_vars.h ev_wrap.h event_compat.h ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c ev.3 ev.pod ev.html /;
|
||||
s/^(include_HEADERS\s*=)/$1 ev.h event_compat.h /;
|
||||
s/^(EXTRA_DIST\s*=)/$1 libev.m4 ev.h ev_vars.h ev_wrap.h event_compat.h ev++.h ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c ev.3 ev.pod ev.html /;
|
||||
s/^(include_HEADERS\s*=)/$1 ev.h event_compat.h ev++.h /;
|
||||
s/^(CORE_SRC\s*=)/$1 ev.c /;
|
||||
s/^(SYS_LIBS\s*=)/$1 -lm /;
|
||||
s/libevent/libev/g;
|
||||
|
|
Loading…
Reference in New Issue