mirror of /home/gitosis/repositories/libev.git
*** empty log message ***
This commit is contained in:
parent
4349718347
commit
3035ff96e0
1
Changes
1
Changes
|
@ -17,6 +17,7 @@ TODO: fix signal handling(?) under win32
|
|||
- add documentation section about priorites.
|
||||
- add a glossary to the dcoumentation.
|
||||
- extend the ev_fork description slightly.
|
||||
- optimize a jump out of call_pending.
|
||||
|
||||
3.53 Sun Feb 15 02:38:20 CET 2009
|
||||
- fix a bug in event pipe creation on win32 that would cause a
|
||||
|
|
|
@ -41,6 +41,7 @@ ev_prepare_start
|
|||
ev_prepare_stop
|
||||
ev_recommended_backends
|
||||
ev_ref
|
||||
ev_resume
|
||||
ev_set_allocator
|
||||
ev_set_io_collect_interval
|
||||
ev_set_syserr_cb
|
||||
|
@ -52,6 +53,7 @@ ev_stat_start
|
|||
ev_stat_stat
|
||||
ev_stat_stop
|
||||
ev_supported_backends
|
||||
ev_suspend
|
||||
ev_time
|
||||
ev_timer_again
|
||||
ev_timer_start
|
||||
|
|
93
ev.c
93
ev.c
|
@ -480,25 +480,27 @@ ev_realloc (void *ptr, long size)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* file descriptor info structure */
|
||||
typedef struct
|
||||
{
|
||||
WL head;
|
||||
unsigned char events;
|
||||
unsigned char reify;
|
||||
unsigned char emask; /* the epoll backend stores the actual kernel mask in here */
|
||||
unsigned char events; /* the events watched for */
|
||||
unsigned char reify; /* flag set when this ANFD needs reification */
|
||||
unsigned char emask; /* the epoll backend stores the actual kernel mask in here */
|
||||
unsigned char unused;
|
||||
#if EV_USE_EPOLL
|
||||
unsigned int egen; /* generation counter to counter epoll bugs */
|
||||
unsigned int egen; /* generation counter to counter epoll bugs */
|
||||
#endif
|
||||
#if EV_SELECT_IS_WINSOCKET
|
||||
SOCKET handle;
|
||||
#endif
|
||||
} ANFD;
|
||||
|
||||
/* stores the pending event set for a given watcher */
|
||||
typedef struct
|
||||
{
|
||||
W w;
|
||||
int events;
|
||||
int events; /* the pending event set for the given watcher */
|
||||
} ANPENDING;
|
||||
|
||||
#if EV_USE_INOTIFY
|
||||
|
@ -511,6 +513,7 @@ typedef struct
|
|||
|
||||
/* Heap Entry */
|
||||
#if EV_HEAP_CACHE_AT
|
||||
/* a heap element */
|
||||
typedef struct {
|
||||
ev_tstamp at;
|
||||
WT w;
|
||||
|
@ -520,6 +523,7 @@ typedef struct
|
|||
#define ANHE_at(he) (he).at /* access cached at, read-only */
|
||||
#define ANHE_at_cache(he) (he).at = (he).w->at /* update at from watcher */
|
||||
#else
|
||||
/* a heap element */
|
||||
typedef WT ANHE;
|
||||
|
||||
#define ANHE_w(he) (he)
|
||||
|
@ -627,6 +631,8 @@ ev_sleep (ev_tstamp delay)
|
|||
|
||||
#define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
|
||||
|
||||
/* find a suitable new size for the given array, */
|
||||
/* hopefully by rounding to a ncie-to-malloc size */
|
||||
inline_size int
|
||||
array_nextsize (int elem, int cur, int cnt)
|
||||
{
|
||||
|
@ -682,6 +688,12 @@ array_realloc (int elem, void *base, int *cur, int cnt)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* dummy callback for pending events */
|
||||
static void noinline
|
||||
pendingcb (EV_P_ ev_prepare *w, int revents)
|
||||
{
|
||||
}
|
||||
|
||||
void noinline
|
||||
ev_feed_event (EV_P_ void *w, int revents)
|
||||
{
|
||||
|
@ -747,6 +759,8 @@ ev_feed_fd_event (EV_P_ int fd, int revents)
|
|||
fd_event (EV_A_ fd, revents);
|
||||
}
|
||||
|
||||
/* make sure the external fd watch events are in-sync */
|
||||
/* with the kernel/libev internal state */
|
||||
inline_size void
|
||||
fd_reify (EV_P)
|
||||
{
|
||||
|
@ -791,6 +805,7 @@ fd_reify (EV_P)
|
|||
fdchangecnt = 0;
|
||||
}
|
||||
|
||||
/* something about the given fd changed */
|
||||
inline_size void
|
||||
fd_change (EV_P_ int fd, int flags)
|
||||
{
|
||||
|
@ -805,6 +820,7 @@ fd_change (EV_P_ int fd, int flags)
|
|||
}
|
||||
}
|
||||
|
||||
/* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */
|
||||
inline_speed void
|
||||
fd_kill (EV_P_ int fd)
|
||||
{
|
||||
|
@ -817,6 +833,7 @@ fd_kill (EV_P_ int fd)
|
|||
}
|
||||
}
|
||||
|
||||
/* check whether the given fd is atcually valid, for error recovery */
|
||||
inline_size int
|
||||
fd_valid (int fd)
|
||||
{
|
||||
|
@ -991,6 +1008,7 @@ upheap (ANHE *heap, int k)
|
|||
ev_active (ANHE_w (he)) = k;
|
||||
}
|
||||
|
||||
/* move an element suitably so it is in a correct place */
|
||||
inline_size void
|
||||
adjustheap (ANHE *heap, int N, int k)
|
||||
{
|
||||
|
@ -1014,6 +1032,7 @@ reheap (ANHE *heap, int N)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* associate signal watchers to a signal signal */
|
||||
typedef struct
|
||||
{
|
||||
WL head;
|
||||
|
@ -1027,6 +1046,8 @@ static EV_ATOMIC_T gotsig;
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* used to prepare libev internal fd's */
|
||||
/* this is not fork-safe */
|
||||
inline_speed void
|
||||
fd_intern (int fd)
|
||||
{
|
||||
|
@ -1042,14 +1063,14 @@ fd_intern (int fd)
|
|||
static void noinline
|
||||
evpipe_init (EV_P)
|
||||
{
|
||||
if (!ev_is_active (&pipeev))
|
||||
if (!ev_is_active (&pipe_w))
|
||||
{
|
||||
#if EV_USE_EVENTFD
|
||||
if ((evfd = eventfd (0, 0)) >= 0)
|
||||
{
|
||||
evpipe [0] = -1;
|
||||
fd_intern (evfd);
|
||||
ev_io_set (&pipeev, evfd, EV_READ);
|
||||
ev_io_set (&pipe_w, evfd, EV_READ);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -1059,10 +1080,10 @@ evpipe_init (EV_P)
|
|||
|
||||
fd_intern (evpipe [0]);
|
||||
fd_intern (evpipe [1]);
|
||||
ev_io_set (&pipeev, evpipe [0], EV_READ);
|
||||
ev_io_set (&pipe_w, evpipe [0], EV_READ);
|
||||
}
|
||||
|
||||
ev_io_start (EV_A_ &pipeev);
|
||||
ev_io_start (EV_A_ &pipe_w);
|
||||
ev_unref (EV_A); /* watcher should not keep loop alive */
|
||||
}
|
||||
}
|
||||
|
@ -1090,6 +1111,8 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
|
|||
}
|
||||
}
|
||||
|
||||
/* called whenever the libev signal pipe */
|
||||
/* got some events (signal, async) */
|
||||
static void
|
||||
pipecb (EV_P_ ev_io *iow, int revents)
|
||||
{
|
||||
|
@ -1181,6 +1204,7 @@ static ev_signal childev;
|
|||
# define WIFCONTINUED(status) 0
|
||||
#endif
|
||||
|
||||
/* handle a single child status event */
|
||||
inline_speed void
|
||||
child_reap (EV_P_ int chain, int pid, int status)
|
||||
{
|
||||
|
@ -1204,6 +1228,7 @@ child_reap (EV_P_ int chain, int pid, int status)
|
|||
# define WCONTINUED 0
|
||||
#endif
|
||||
|
||||
/* called on sigchld etc., calls waitpid */
|
||||
static void
|
||||
childcb (EV_P_ ev_signal *sw, int revents)
|
||||
{
|
||||
|
@ -1338,6 +1363,7 @@ ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval)
|
|||
timeout_blocktime = interval;
|
||||
}
|
||||
|
||||
/* initialise a loop structure, must be zero-initialised */
|
||||
static void noinline
|
||||
loop_init (EV_P_ unsigned int flags)
|
||||
{
|
||||
|
@ -1407,20 +1433,23 @@ loop_init (EV_P_ unsigned int flags)
|
|||
if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
|
||||
#endif
|
||||
|
||||
ev_init (&pipeev, pipecb);
|
||||
ev_set_priority (&pipeev, EV_MAXPRI);
|
||||
ev_prepare_init (&pending_w, pendingcb);
|
||||
|
||||
ev_init (&pipe_w, pipecb);
|
||||
ev_set_priority (&pipe_w, EV_MAXPRI);
|
||||
}
|
||||
}
|
||||
|
||||
/* free up a loop structure */
|
||||
static void noinline
|
||||
loop_destroy (EV_P)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ev_is_active (&pipeev))
|
||||
if (ev_is_active (&pipe_w))
|
||||
{
|
||||
ev_ref (EV_A); /* signal watcher */
|
||||
ev_io_stop (EV_A_ &pipeev);
|
||||
ev_io_stop (EV_A_ &pipe_w);
|
||||
|
||||
#if EV_USE_EVENTFD
|
||||
if (evfd >= 0)
|
||||
|
@ -1507,7 +1536,7 @@ loop_fork (EV_P)
|
|||
infy_fork (EV_A);
|
||||
#endif
|
||||
|
||||
if (ev_is_active (&pipeev))
|
||||
if (ev_is_active (&pipe_w))
|
||||
{
|
||||
/* this "locks" the handlers against writing to the pipe */
|
||||
/* while we modify the fd vars */
|
||||
|
@ -1517,7 +1546,7 @@ loop_fork (EV_P)
|
|||
#endif
|
||||
|
||||
ev_ref (EV_A);
|
||||
ev_io_stop (EV_A_ &pipeev);
|
||||
ev_io_stop (EV_A_ &pipe_w);
|
||||
|
||||
#if EV_USE_EVENTFD
|
||||
if (evfd >= 0)
|
||||
|
@ -1532,7 +1561,7 @@ loop_fork (EV_P)
|
|||
|
||||
evpipe_init (EV_A);
|
||||
/* now iterate over everything, in case we missed something */
|
||||
pipecb (EV_A_ &pipeev, EV_READ);
|
||||
pipecb (EV_A_ &pipe_w, EV_READ);
|
||||
}
|
||||
|
||||
postfork = 0;
|
||||
|
@ -1748,18 +1777,18 @@ call_pending (EV_P)
|
|||
{
|
||||
ANPENDING *p = pendings [pri] + --pendingcnt [pri];
|
||||
|
||||
if (expect_true (p->w))
|
||||
{
|
||||
/*assert (("libev: non-pending watcher on pending list", p->w->pending));*/
|
||||
/*assert (("libev: non-pending watcher on pending list", p->w->pending));*/
|
||||
/* ^ this is no longer true, as pending_w could be here */
|
||||
|
||||
p->w->pending = 0;
|
||||
EV_CB_INVOKE (p->w, p->events);
|
||||
EV_FREQUENT_CHECK;
|
||||
}
|
||||
p->w->pending = 0;
|
||||
EV_CB_INVOKE (p->w, p->events);
|
||||
EV_FREQUENT_CHECK;
|
||||
}
|
||||
}
|
||||
|
||||
#if EV_IDLE_ENABLE
|
||||
/* make idle watchers pending. this handles the "call-idle */
|
||||
/* only when higher priorities are idle" logic */
|
||||
inline_size void
|
||||
idle_reify (EV_P)
|
||||
{
|
||||
|
@ -1782,6 +1811,7 @@ idle_reify (EV_P)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* make timers pending */
|
||||
inline_size void
|
||||
timers_reify (EV_P)
|
||||
{
|
||||
|
@ -1820,6 +1850,7 @@ timers_reify (EV_P)
|
|||
}
|
||||
|
||||
#if EV_PERIODIC_ENABLE
|
||||
/* make periodics pending */
|
||||
inline_size void
|
||||
periodics_reify (EV_P)
|
||||
{
|
||||
|
@ -1876,6 +1907,8 @@ periodics_reify (EV_P)
|
|||
}
|
||||
}
|
||||
|
||||
/* simply recalculate all periodics */
|
||||
/* TODO: maybe ensure that at leats one event happens when jumping forward? */
|
||||
static void noinline
|
||||
periodics_reschedule (EV_P)
|
||||
{
|
||||
|
@ -1898,6 +1931,7 @@ periodics_reschedule (EV_P)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* adjust all timers by a given offset */
|
||||
static void noinline
|
||||
timers_reschedule (EV_P_ ev_tstamp adjust)
|
||||
{
|
||||
|
@ -1911,6 +1945,8 @@ timers_reschedule (EV_P_ ev_tstamp adjust)
|
|||
}
|
||||
}
|
||||
|
||||
/* fetch new monotonic and realtime times from the kernel */
|
||||
/* also detetc if there was a timejump, and act accordingly */
|
||||
inline_speed void
|
||||
time_update (EV_P_ ev_tstamp max_block)
|
||||
{
|
||||
|
@ -2139,11 +2175,13 @@ ev_resume (EV_P)
|
|||
ev_now_update (EV_A);
|
||||
timers_reschedule (EV_A_ mn_now - mn_prev);
|
||||
#if EV_PERIODIC_ENABLE
|
||||
/* TODO: really do this? */
|
||||
periodics_reschedule (EV_A);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* singly-linked list management, used when the expected list length is short */
|
||||
|
||||
inline_size void
|
||||
wlist_add (WL *head, WL elem)
|
||||
|
@ -2167,12 +2205,13 @@ wlist_del (WL *head, WL elem)
|
|||
}
|
||||
}
|
||||
|
||||
/* internal, faster, version of ev_clear_pending */
|
||||
inline_speed void
|
||||
clear_pending (EV_P_ W w)
|
||||
{
|
||||
if (w->pending)
|
||||
{
|
||||
pendings [ABSPRI (w)][w->pending - 1].w = 0;
|
||||
pendings [ABSPRI (w)][w->pending - 1].w = (W)&pending_w;
|
||||
w->pending = 0;
|
||||
}
|
||||
}
|
||||
|
@ -2186,8 +2225,8 @@ ev_clear_pending (EV_P_ void *w)
|
|||
if (expect_true (pending))
|
||||
{
|
||||
ANPENDING *p = pendings [ABSPRI (w_)] + pending - 1;
|
||||
p->w = (W)&pending_w;
|
||||
w_->pending = 0;
|
||||
p->w = 0;
|
||||
return p->events;
|
||||
}
|
||||
else
|
||||
|
@ -3203,7 +3242,7 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#if 0
|
||||
#if EV_WALK_ENABLE
|
||||
void
|
||||
ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
|
||||
{
|
||||
|
@ -3229,7 +3268,7 @@ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
|
|||
;
|
||||
else
|
||||
#endif
|
||||
if ((ev_io *)wl != &pipeev)
|
||||
if ((ev_io *)wl != &pipe_w)
|
||||
if (types & EV_IO)
|
||||
cb (EV_A_ EV_IO, wl);
|
||||
|
||||
|
|
6
ev.h
6
ev.h
|
@ -82,6 +82,10 @@ typedef double ev_tstamp;
|
|||
# define EV_ASYNC_ENABLE 1
|
||||
#endif
|
||||
|
||||
#ifndef EV_WALK_ENABLE
|
||||
# define EV_WALK_ENABLE 0 /* not yet */
|
||||
#endif
|
||||
|
||||
#ifndef EV_ATOMIC_T
|
||||
# include <signal.h>
|
||||
# define EV_ATOMIC_T sig_atomic_t volatile
|
||||
|
@ -494,7 +498,7 @@ void ev_default_destroy (void); /* destroy the default loop */
|
|||
/* you can actually call it at any time, anywhere :) */
|
||||
void ev_default_fork (void);
|
||||
|
||||
#if 0
|
||||
#if EV_WALK_ENABLE
|
||||
/* walk (almost) all watchers in the loop of a given type, invoking the */
|
||||
/* callback on every such watcher. The callback might stop the watcher, */
|
||||
/* but do nothing else with the loop */
|
||||
|
|
9
ev.pod
9
ev.pod
|
@ -1467,10 +1467,11 @@ detecting time jumps is hard, and some inaccuracies are unavoidable (the
|
|||
monotonic clock option helps a lot here).
|
||||
|
||||
The callback is guaranteed to be invoked only I<after> its timeout 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).
|
||||
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 with later time-out values (but this is no longer true when a
|
||||
callback calls C<ev_loop> recursively).
|
||||
|
||||
=head3 Be smart about timeouts
|
||||
|
||||
|
|
27
ev_vars.h
27
ev_vars.h
|
@ -55,11 +55,24 @@ VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */
|
|||
VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
|
||||
VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))
|
||||
|
||||
VARx(ANFD *, anfds)
|
||||
VARx(int, anfdmax)
|
||||
|
||||
VAR (pendings, ANPENDING *pendings [NUMPRI])
|
||||
VAR (pendingmax, int pendingmax [NUMPRI])
|
||||
VAR (pendingcnt, int pendingcnt [NUMPRI])
|
||||
VARx(ev_prepare, pending_w) /* dummy pending watcher */
|
||||
|
||||
/* for reverse feeding of events */
|
||||
VARx(W *, rfeeds)
|
||||
VARx(int, rfeedmax)
|
||||
VARx(int, rfeedcnt)
|
||||
|
||||
#if EV_USE_EVENTFD || EV_GENWRAP
|
||||
VARx(int, evfd)
|
||||
#endif
|
||||
VAR (evpipe, int evpipe [2])
|
||||
VARx(ev_io, pipeev)
|
||||
VARx(ev_io, pipe_w)
|
||||
|
||||
#if !defined(_WIN32) || EV_GENWRAP
|
||||
VARx(pid_t, curpid)
|
||||
|
@ -104,18 +117,6 @@ VARx(struct port_event *, port_events)
|
|||
VARx(int, port_eventmax)
|
||||
#endif
|
||||
|
||||
VARx(ANFD *, anfds)
|
||||
VARx(int, anfdmax)
|
||||
|
||||
VAR (pendings, ANPENDING *pendings [NUMPRI])
|
||||
VAR (pendingmax, int pendingmax [NUMPRI])
|
||||
VAR (pendingcnt, int pendingcnt [NUMPRI])
|
||||
|
||||
/* for reverse feeding of events */
|
||||
VARx(W *, rfeeds)
|
||||
VARx(int, rfeedmax)
|
||||
VARx(int, rfeedcnt)
|
||||
|
||||
VARx(int *, fdchanges)
|
||||
VARx(int, fdchangemax)
|
||||
VARx(int, fdchangecnt)
|
||||
|
|
38
ev_wrap.h
38
ev_wrap.h
|
@ -13,9 +13,18 @@
|
|||
#define backend_fudge ((loop)->backend_fudge)
|
||||
#define backend_modify ((loop)->backend_modify)
|
||||
#define backend_poll ((loop)->backend_poll)
|
||||
#define anfds ((loop)->anfds)
|
||||
#define anfdmax ((loop)->anfdmax)
|
||||
#define pendings ((loop)->pendings)
|
||||
#define pendingmax ((loop)->pendingmax)
|
||||
#define pendingcnt ((loop)->pendingcnt)
|
||||
#define pending_w ((loop)->pending_w)
|
||||
#define rfeeds ((loop)->rfeeds)
|
||||
#define rfeedmax ((loop)->rfeedmax)
|
||||
#define rfeedcnt ((loop)->rfeedcnt)
|
||||
#define evfd ((loop)->evfd)
|
||||
#define evpipe ((loop)->evpipe)
|
||||
#define pipeev ((loop)->pipeev)
|
||||
#define pipe_w ((loop)->pipe_w)
|
||||
#define curpid ((loop)->curpid)
|
||||
#define postfork ((loop)->postfork)
|
||||
#define vec_ri ((loop)->vec_ri)
|
||||
|
@ -38,14 +47,6 @@
|
|||
#define kqueue_eventmax ((loop)->kqueue_eventmax)
|
||||
#define port_events ((loop)->port_events)
|
||||
#define port_eventmax ((loop)->port_eventmax)
|
||||
#define anfds ((loop)->anfds)
|
||||
#define anfdmax ((loop)->anfdmax)
|
||||
#define pendings ((loop)->pendings)
|
||||
#define pendingmax ((loop)->pendingmax)
|
||||
#define pendingcnt ((loop)->pendingcnt)
|
||||
#define rfeeds ((loop)->rfeeds)
|
||||
#define rfeedmax ((loop)->rfeedmax)
|
||||
#define rfeedcnt ((loop)->rfeedcnt)
|
||||
#define fdchanges ((loop)->fdchanges)
|
||||
#define fdchangemax ((loop)->fdchangemax)
|
||||
#define fdchangecnt ((loop)->fdchangecnt)
|
||||
|
@ -90,9 +91,18 @@
|
|||
#undef backend_fudge
|
||||
#undef backend_modify
|
||||
#undef backend_poll
|
||||
#undef anfds
|
||||
#undef anfdmax
|
||||
#undef pendings
|
||||
#undef pendingmax
|
||||
#undef pendingcnt
|
||||
#undef pending_w
|
||||
#undef rfeeds
|
||||
#undef rfeedmax
|
||||
#undef rfeedcnt
|
||||
#undef evfd
|
||||
#undef evpipe
|
||||
#undef pipeev
|
||||
#undef pipe_w
|
||||
#undef curpid
|
||||
#undef postfork
|
||||
#undef vec_ri
|
||||
|
@ -115,14 +125,6 @@
|
|||
#undef kqueue_eventmax
|
||||
#undef port_events
|
||||
#undef port_eventmax
|
||||
#undef anfds
|
||||
#undef anfdmax
|
||||
#undef pendings
|
||||
#undef pendingmax
|
||||
#undef pendingcnt
|
||||
#undef rfeeds
|
||||
#undef rfeedmax
|
||||
#undef rfeedcnt
|
||||
#undef fdchanges
|
||||
#undef fdchangemax
|
||||
#undef fdchangecnt
|
||||
|
|
Loading…
Reference in New Issue