static int have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
-#if WIN32
-/* note: the comment below could not be substantiated, but what would I care */
-/* MSDN says this is required to handle SIGFPE */
-volatile double SIGFPE_REQ = 0.0f;
-
-static int
-ev_socketpair_tcp (int filedes [2])
-{
- struct sockaddr_in addr = { 0 };
- int addr_size = sizeof (addr);
- SOCKET listener;
- SOCKET sock [2] = { -1, -1 };
-
- if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
- return -1;
-
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- addr.sin_port = 0;
-
- if (bind (listener, (struct sockaddr *)&addr, addr_size))
- goto fail;
-
- if (getsockname(listener, (struct sockaddr *)&addr, &addr_size))
- goto fail;
-
- if (listen (listener, 1))
- goto fail;
-
- if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
- goto fail;
-
- if (connect (sock[0], (struct sockaddr *)&addr, addr_size))
- goto fail;
-
- if ((sock[1] = accept (listener, 0, 0)) < 0)
- goto fail;
-
- closesocket (listener);
-
- filedes [0] = sock [0];
- filedes [1] = sock [1];
-
- return 0;
-
-fail:
- closesocket (listener);
-
- if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
- if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);
-
- return -1;
-}
-
-# define ev_pipe(filedes) ev_socketpair_tcp (filedes)
-#else
-# define ev_pipe(filedes) pipe (filedes)
-#endif
+#include "ev_win32.c"
/*****************************************************************************/
return rt_now;
}
-#define array_roundsize(base,n) ((n) | 4 & ~3)
+#define array_roundsize(type,n) ((n) | 4 & ~3)
-#define array_needsize(base,cur,cnt,init) \
+#define array_needsize(type,base,cur,cnt,init) \
if (expect_false ((cnt) > cur)) \
{ \
int newcnt = cur; \
do \
{ \
- newcnt = array_roundsize (base, newcnt << 1); \
+ newcnt = array_roundsize (type, newcnt << 1); \
} \
while ((cnt) > newcnt); \
\
- base = ev_realloc (base, sizeof (*base) * (newcnt)); \
+ base = (type *)ev_realloc (base, sizeof (type) * (newcnt));\
init (base + cur, newcnt - cur); \
cur = newcnt; \
}
-#define array_slim(stem) \
+#define array_slim(type,stem) \
if (stem ## max < array_roundsize (stem ## cnt >> 2)) \
{ \
stem ## max = array_roundsize (stem ## cnt >> 1); \
- base = ev_realloc (base, sizeof (*base) * (stem ## max)); \
+ base = (type *)ev_realloc (base, sizeof (type) * (stem ## max));\
fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\
}
}
w->pending = ++pendingcnt [ABSPRI (w)];
- array_needsize (pendings [ABSPRI (w)], pendingmax [ABSPRI (w)], pendingcnt [ABSPRI (w)], (void));
+ array_needsize (ANPENDING, pendings [ABSPRI (w)], pendingmax [ABSPRI (w)], pendingcnt [ABSPRI (w)], (void));
pendings [ABSPRI (w)][w->pending - 1].w = w;
pendings [ABSPRI (w)][w->pending - 1].events = events;
}
anfds [fd].reify = 1;
++fdchangecnt;
- array_needsize (fdchanges, fdchangemax, fdchangecnt, (void));
+ array_needsize (int, fdchanges, fdchangemax, fdchangecnt, (void));
fdchanges [fdchangecnt - 1] = fd;
}
{
int old_errno = errno;
gotsig = 1;
+#ifdef WIN32
+ send (sigpipe [1], &signum, 1, MSG_DONTWAIT);
+#else
write (sigpipe [1], &signum, 1);
+#endif
errno = old_errno;
}
}
WL w;
int signum;
+#ifdef WIN32
+ recv (sigpipe [0], &revents, 1, MSG_DONTWAIT);
+#else
read (sigpipe [0], &revents, 1);
+#endif
gotsig = 0;
for (signum = signalmax; signum--; )
close (sigpipe [0]);
close (sigpipe [1]);
- while (ev_pipe (sigpipe))
+ while (pipe (sigpipe))
syserr ("(libev) error creating pipe");
siginit (EV_A);
ev_default_loop (int methods)
{
if (sigpipe [0] == sigpipe [1])
- if (ev_pipe (sigpipe))
+ if (pipe (sigpipe))
return 0;
if (!default_loop)
/*****************************************************************************/
+static int
+any_pending (EV_P)
+{
+ int pri;
+
+ for (pri = NUMPRI; pri--; )
+ if (pendingcnt [pri])
+ return 1;
+
+ return 0;
+}
+
static void
call_pending (EV_P)
{
assert (("inactive timer on periodic heap detected", ev_is_active (w)));
/* first reschedule or stop timer */
- if (w->interval)
+ if (w->reschedule_cb)
+ {
+ ev_tstamp at = ((WT)w)->at = w->reschedule_cb (w, rt_now + 0.0001);
+
+ assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > rt_now));
+ downheap ((WT *)periodics, periodiccnt, 0);
+ }
+ else if (w->interval)
{
((WT)w)->at += floor ((rt_now - ((WT)w)->at) / w->interval + 1.) * w->interval;
assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > rt_now));
{
struct ev_periodic *w = periodics [i];
- if (w->interval)
- {
- ev_tstamp diff = ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
-
- if (fabs (diff) >= 1e-4)
- {
- ev_periodic_stop (EV_A_ w);
- ev_periodic_start (EV_A_ w);
-
- i = 0; /* restart loop, inefficient, but time jumps should be rare */
- }
- }
+ if (w->reschedule_cb)
+ ((WT)w)->at = w->reschedule_cb (w, rt_now);
+ else if (w->interval)
+ ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
}
+
+ /* now rebuild the heap */
+ for (i = periodiccnt >> 1; i--; )
+ downheap ((WT *)periodics, periodiccnt, i);
}
inline int
/* calculate blocking time */
- /* we only need this for !monotonic clockor timers, but as we basically
+ /* we only need this for !monotonic clock or timers, but as we basically
always have timers, we just calculate it always */
#if EV_USE_MONOTONIC
if (expect_true (have_monotonic))
periodics_reify (EV_A); /* absolute timers called first */
/* queue idle watchers unless io or timers are pending */
- if (!pendingcnt)
+ if (idlecnt && !any_pending (EV_A))
queue_events (EV_A_ (W *)idles, idlecnt, EV_IDLE);
/* queue check watchers, to be executed first */
assert (("ev_io_start called with negative fd", fd >= 0));
ev_start (EV_A_ (W)w, 1);
- array_needsize (anfds, anfdmax, fd + 1, anfds_init);
+ array_needsize (ANFD, anfds, anfdmax, fd + 1, anfds_init);
wlist_add ((WL *)&anfds[fd].head, (WL)w);
fd_change (EV_A_ fd);
assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
ev_start (EV_A_ (W)w, ++timercnt);
- array_needsize (timers, timermax, timercnt, (void));
+ array_needsize (struct ev_timer *, timers, timermax, timercnt, (void));
timers [timercnt - 1] = w;
upheap ((WT *)timers, timercnt - 1);
if (ev_is_active (w))
return;
- assert (("ev_periodic_start called with negative interval value", w->interval >= 0.));
-
- /* this formula differs from the one in periodic_reify because we do not always round up */
- if (w->interval)
- ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
+ if (w->reschedule_cb)
+ ((WT)w)->at = w->reschedule_cb (w, rt_now);
+ else if (w->interval)
+ {
+ assert (("ev_periodic_start called with negative interval value", w->interval >= 0.));
+ /* this formula differs from the one in periodic_reify because we do not always round up */
+ ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
+ }
ev_start (EV_A_ (W)w, ++periodiccnt);
- array_needsize (periodics, periodicmax, periodiccnt, (void));
+ array_needsize (struct ev_periodic *, periodics, periodicmax, periodiccnt, (void));
periodics [periodiccnt - 1] = w;
upheap ((WT *)periodics, periodiccnt - 1);
ev_stop (EV_A_ (W)w);
}
+void
+ev_periodic_again (EV_P_ struct ev_periodic *w)
+{
+ ev_periodic_stop (EV_A_ w);
+ ev_periodic_start (EV_A_ w);
+}
+
void
ev_idle_start (EV_P_ struct ev_idle *w)
{
return;
ev_start (EV_A_ (W)w, ++idlecnt);
- array_needsize (idles, idlemax, idlecnt, (void));
+ array_needsize (struct ev_idle *, idles, idlemax, idlecnt, (void));
idles [idlecnt - 1] = w;
}
return;
ev_start (EV_A_ (W)w, ++preparecnt);
- array_needsize (prepares, preparemax, preparecnt, (void));
+ array_needsize (struct ev_prepare *, prepares, preparemax, preparecnt, (void));
prepares [preparecnt - 1] = w;
}
return;
ev_start (EV_A_ (W)w, ++checkcnt);
- array_needsize (checks, checkmax, checkcnt, (void));
+ array_needsize (struct ev_check *, checks, checkmax, checkcnt, (void));
checks [checkcnt - 1] = w;
}
assert (("ev_signal_start called with illegal signal number", w->signum > 0));
ev_start (EV_A_ (W)w, 1);
- array_needsize (signals, signalmax, w->signum, signals_init);
+ array_needsize (ANSIG, signals, signalmax, w->signum, signals_init);
wlist_add ((WL *)&signals [w->signum - 1].head, (WL)w);
if (!((WL)w)->next)
void
ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg)
{
- struct ev_once *once = ev_malloc (sizeof (struct ev_once));
+ struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
if (!once)
cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMEOUT, arg);