#include <signal.h>
-#ifndef WIN32
+#ifndef _WIN32
# include <unistd.h>
# include <sys/time.h>
# include <sys/wait.h>
+#else
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# ifndef EV_SELECT_IS_WINSOCKET
+# define EV_SELECT_IS_WINSOCKET 1
+# endif
#endif
+
/**/
#ifndef EV_USE_MONOTONIC
# define EV_USE_KQUEUE 0
#endif
-#ifndef EV_USE_WIN32
-# ifdef WIN32
-# define EV_USE_WIN32 0 /* it does not exist, use select */
-# undef EV_USE_SELECT
-# define EV_USE_SELECT 1
-# else
-# define EV_USE_WIN32 0
-# endif
-#endif
-
#ifndef EV_USE_REALTIME
# define EV_USE_REALTIME 1
#endif
# define EV_USE_REALTIME 0
#endif
+#if EV_SELECT_IS_WINSOCKET
+# include <winsock.h>
+#endif
+
/**/
#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
#define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
#define ABSPRI(w) ((w)->priority - EV_MINPRI)
+#define EMPTY /* required for microsofts broken pseudo-c compiler */
+
typedef struct ev_watcher *W;
typedef struct ev_watcher_list *WL;
typedef struct ev_watcher_time *WT;
static int have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
-#ifdef WIN32
+#ifdef _WIN32
# include "ev_win32.c"
#endif
WL head;
unsigned char events;
unsigned char reify;
+#if EV_SELECT_IS_WINSOCKET
+ SOCKET handle;
+#endif
} ANFD;
typedef struct
fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\
}
-/* microsoft's pseudo-c is quite far from C as the rest of the world and the standard knows it */
-/* bringing us everlasting joy in form of stupid extra macros that are not required in C */
-#define array_free_microshit(stem) \
- ev_free (stem ## s); stem ## cnt = stem ## max = 0;
-
#define array_free(stem, idx) \
ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0;
for (w = (struct ev_io *)anfd->head; w; w = (struct ev_io *)((WL)w)->next)
events |= w->events;
+#if EV_SELECT_IS_WINSOCKET
+ if (events)
+ {
+ unsigned long argp;
+ anfd->handle = _get_osfhandle (fd);
+ assert (("libev only supports socket fds in this configuration", ioctlsocket (anfd->handle, FIONREAD, &argp) == 0));
+ }
+#endif
+
anfd->reify = 0;
method_modify (EV_A_ fd, anfd->events, events);
static int
fd_valid (int fd)
{
-#ifdef WIN32
- return !!win32_get_osfhandle (fd);
+#ifdef _WIN32
+ return _get_osfhandle (fd) != -1;
#else
return fcntl (fd, F_GETFD) != -1;
#endif
static void
sighandler (int signum)
{
-#if WIN32
+#if _WIN32
signal (signum, sighandler);
#endif
{
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;
}
}
{
int signum;
-#ifdef WIN32
- recv (sigpipe [0], &revents, 1, MSG_DONTWAIT);
-#else
read (sigpipe [0], &revents, 1);
-#endif
gotsig = 0;
for (signum = signalmax; signum--; )
ev_feed_signal_event (EV_A_ signum + 1);
}
+inline void
+fd_intern (int fd)
+{
+#ifdef _WIN32
+ int arg = 1;
+ ioctlsocket (_get_osfhandle (fd), FIONBIO, &arg);
+#else
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
+ fcntl (fd, F_SETFL, O_NONBLOCK);
+#endif
+}
+
static void
siginit (EV_P)
{
-#ifndef WIN32
- fcntl (sigpipe [0], F_SETFD, FD_CLOEXEC);
- fcntl (sigpipe [1], F_SETFD, FD_CLOEXEC);
-
- /* rather than sort out wether we really need nb, set it */
- fcntl (sigpipe [0], F_SETFL, O_NONBLOCK);
- fcntl (sigpipe [1], F_SETFL, O_NONBLOCK);
-#endif
+ fd_intern (sigpipe [0]);
+ fd_intern (sigpipe [1]);
ev_io_set (&sigev, sigpipe [0], EV_READ);
ev_io_start (EV_A_ &sigev);
static struct ev_child *childs [PID_HASHSIZE];
-#ifndef WIN32
+#ifndef _WIN32
static struct ev_signal childev;
static int
enable_secure (void)
{
-#ifdef WIN32
+#ifdef _WIN32
return 0;
#else
return getuid () != geteuid ()
methods = EVMETHOD_ANY;
method = 0;
-#if EV_USE_WIN32
- if (!method && (methods & EVMETHOD_WIN32 )) method = win32_init (EV_A_ methods);
-#endif
#if EV_USE_KQUEUE
if (!method && (methods & EVMETHOD_KQUEUE)) method = kqueue_init (EV_A_ methods);
#endif
{
int i;
-#if EV_USE_WIN32
- if (method == EVMETHOD_WIN32 ) win32_destroy (EV_A);
-#endif
#if EV_USE_KQUEUE
if (method == EVMETHOD_KQUEUE) kqueue_destroy (EV_A);
#endif
array_free (pending, [i]);
/* have to use the microsoft-never-gets-it-right macro */
- array_free_microshit (fdchange);
- array_free_microshit (timer);
+ array_free (fdchange, EMPTY);
+ array_free (timer, EMPTY);
#if EV_PERIODICS
- array_free_microshit (periodic);
+ array_free (periodic, EMPTY);
#endif
- array_free_microshit (idle);
- array_free_microshit (prepare);
- array_free_microshit (check);
+ array_free (idle, EMPTY);
+ array_free (prepare, EMPTY);
+ array_free (check, EMPTY);
method = 0;
}
{
siginit (EV_A);
-#ifndef WIN32
+#ifndef _WIN32
ev_signal_init (&childev, childcb, SIGCHLD);
ev_set_priority (&childev, EV_MAXPRI);
ev_signal_start (EV_A_ &childev);
struct ev_loop *loop = default_loop;
#endif
-#ifndef WIN32
+#ifndef _WIN32
ev_ref (EV_A); /* child watcher */
ev_signal_stop (EV_A_ &childev);
#endif
if (!((WL)w)->next)
{
-#if WIN32
+#if _WIN32
signal (w->signum, sighandler);
#else
struct sigaction sa;
/* can be used to add custom fields to all watchers, while losing binary compatibility */
#ifndef EV_COMMON
-# define EV_COMMON void *data
+# define EV_COMMON void *data;
#endif
#ifndef EV_PROTOTYPES
# define EV_PROTOTYPES 1
int active; /* private */ \
int pending; /* private */ \
int priority; /* private */ \
- EV_COMMON; /* rw */ \
+ EV_COMMON /* rw */ \
EV_CB_DECLARE (type) /* private */
#define EV_WATCHER_LIST(type) \
- EV_WATCHER (type); \
- struct ev_watcher_list *next /* private */
+ EV_WATCHER (type) \
+ struct ev_watcher_list *next; /* private */
#define EV_WATCHER_TIME(type) \
- EV_WATCHER (type); \
- ev_tstamp at /* private */
+ EV_WATCHER (type) \
+ ev_tstamp at; /* private */
/* base class, nothing to see here unless you subclass */
struct ev_watcher
{
- EV_WATCHER (ev_watcher);
+ EV_WATCHER (ev_watcher)
};
/* base class, nothing to see here unless you subclass */
struct ev_watcher_list
{
- EV_WATCHER_LIST (ev_watcher_list);
+ EV_WATCHER_LIST (ev_watcher_list)
};
/* base class, nothing to see here unless you subclass */
struct ev_watcher_time
{
- EV_WATCHER_TIME (ev_watcher_time);
+ EV_WATCHER_TIME (ev_watcher_time)
};
/* invoked after a specific time, repeatable (based on monotonic clock) */
/* revent EV_TIMEOUT */
struct ev_timer
{
- EV_WATCHER_TIME (ev_timer);
+ EV_WATCHER_TIME (ev_timer)
ev_tstamp repeat; /* rw */
};
/* revent EV_PERIODIC */
struct ev_periodic
{
- EV_WATCHER_TIME (ev_periodic);
+ EV_WATCHER_TIME (ev_periodic)
ev_tstamp interval; /* rw */
ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now); /* rw */
/* revent EV_READ, EV_WRITE */
struct ev_io
{
- EV_WATCHER_LIST (ev_io);
+ EV_WATCHER_LIST (ev_io)
int fd; /* ro */
int events; /* ro */
/* revent EV_SIGNAL */
struct ev_signal
{
- EV_WATCHER_LIST (ev_signal);
+ EV_WATCHER_LIST (ev_signal)
int signum; /* ro */
};
/* revent EV_IDLE */
struct ev_idle
{
- EV_WATCHER (ev_idle);
+ EV_WATCHER (ev_idle)
};
/* invoked for each run of the mainloop, just before the blocking call */
/* revent EV_PREPARE */
struct ev_prepare
{
- EV_WATCHER (ev_prepare);
+ EV_WATCHER (ev_prepare)
};
/* invoked for each run of the mainloop, just after the blocking call */
/* revent EV_CHECK */
struct ev_check
{
- EV_WATCHER (ev_check);
+ EV_WATCHER (ev_check)
};
/* invoked when sigchld is received and waitpid indicates the givne pid */
/* does not support priorities */
struct ev_child
{
- EV_WATCHER_LIST (ev_child);
+ EV_WATCHER_LIST (ev_child)
int pid; /* ro */
int rpid; /* rw, holds the received pid */
int ev_default_loop (int methods); /* returns true when successful */
static ev_tstamp
-ev_now ()
+ev_now (void)
{
extern ev_tstamp ev_rt_now;
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef _WIN32
/* for unix systems */
-#if WIN32
-typedef unsigned int uint32_t;
-# ifndef EV_SELECT_USE_FD_SET
-# define EV_SELECT_USE_FD_SET 1
-# endif
-#else
# include <sys/select.h>
# include <inttypes.h>
#endif
-#if EV_SELECT_USE_WIN32_HANDLES
+#ifndef EV_SELECT_USE_FD_SET
+# ifdef NFDBITS
+# define EV_SELECT_USE_FD_SET 0
+# else
+# define EV_SELECT_USE_FD_SET 1
+# endif
+#endif
+
+#if EV_SELECT_IS_WINSOCKET
# undef EV_SELECT_USE_FD_SET
# define EV_SELECT_USE_FD_SET 1
+# undef EINTR
+# define EINTR WSAEINTR
+# undef EBADF
+# define EBADF WSAENOTSOCK
+# undef ENOMEM
+# define ENOMEM (errno + 1)
+#endif
+
+#if !EV_SELECT_USE_FD_SET
+# define NFDBYTES (NFDBITS / 8)
#endif
#include <string.h>
if (oev == nev)
return;
+ {
#if EV_SELECT_USE_FD_SET
-# if EV_SELECT_USE_WIN32_HANDLES
- fd = _get_osfhandle (fd);
- if (fd < 0)
- return;
-# endif
- if (nev & EV_READ)
- FD_SET (fd, (struct fd_set *)vec_ri);
- else
- FD_CLR (fd, (struct fd_set *)vec_ri);
+ #if EV_SELECT_IS_WINSOCKET
+ SOCKET handle = anfds [fd].handle;
+ #else
+ int handle = fd;
+ #endif
+
+ if (nev & EV_READ)
+ FD_SET (handle, (fd_set *)vec_ri);
+ else
+ FD_CLR (handle, (fd_set *)vec_ri);
+
+ if (nev & EV_WRITE)
+ FD_SET (handle, (fd_set *)vec_wi);
+ else
+ FD_CLR (handle, (fd_set *)vec_wi);
- if (nev & EV_WRITE)
- FD_SET (fd, (struct fd_set *)vec_wi);
- else
- FD_CLR (fd, (struct fd_set *)vec_wi);
#else
- {
- int offs = fd >> 3;
- int mask = 1 << (fd & 7);
- if (vec_max < (fd >> 5) + 1)
+ int word = fd / NFDBITS;
+ int mask = 1UL << (fd % NFDBITS);
+
+ if (vec_max < word + 1)
{
- int new_max = (fd >> 5) + 1;
+ int new_max = word + 1;
- vec_ri = (unsigned char *)ev_realloc (vec_ri, new_max * 4);
- vec_ro = (unsigned char *)ev_realloc (vec_ro, new_max * 4); /* could free/malloc */
- vec_wi = (unsigned char *)ev_realloc (vec_wi, new_max * 4);
- vec_wo = (unsigned char *)ev_realloc (vec_wo, new_max * 4); /* could free/malloc */
+ vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES);
+ vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
+ vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
+ vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
for (; vec_max < new_max; ++vec_max)
- ((uint32_t *)vec_ri)[vec_max] =
- ((uint32_t *)vec_wi)[vec_max] = 0;
+ ((fd_mask *)vec_ri)[vec_max] =
+ ((fd_mask *)vec_wi)[vec_max] = 0;
}
- vec_ri [offs] |= mask;
+ ((fd_mask *)vec_ri) [word] |= mask;
if (!(nev & EV_READ))
- vec_ri [offs] &= ~mask;
+ ((fd_mask *)vec_ri) [word] &= ~mask;
- vec_wi [offs] |= mask;
+ ((fd_mask *)vec_wi) [word] |= mask;
if (!(nev & EV_WRITE))
- vec_wi [offs] &= ~mask;
- }
+ ((fd_mask *)vec_wi) [word] &= ~mask;
#endif
+ }
}
static void
select_poll (EV_P_ ev_tstamp timeout)
{
- int word, offs;
struct timeval tv;
int res;
#if EV_SELECT_USE_FD_SET
- memcpy (vec_ro, vec_ri, sizeof (struct fd_set));
- memcpy (vec_wo, vec_wi, sizeof (struct fd_set));
+ memcpy (vec_ro, vec_ri, sizeof (fd_set));
+ memcpy (vec_wo, vec_wi, sizeof (fd_set));
#else
- memcpy (vec_ro, vec_ri, vec_max * 4);
- memcpy (vec_wo, vec_wi, vec_max * 4);
+ memcpy (vec_ro, vec_ri, vec_max * NFDBYTES);
+ memcpy (vec_wo, vec_wi, vec_max * NFDBYTES);
#endif
tv.tv_sec = (long)timeout;
tv.tv_usec = (long)((timeout - (ev_tstamp)tv.tv_sec) * 1e6);
- res = select (vec_max * 32, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
+ res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
if (res < 0)
{
-#ifdef WIN32
- if (errno == WSAEINTR ) errno = EINTR;
- if (errno == WSAENOTSOCK) errno = EBADF;
-#endif
+ #if EV_SELECT_IS_WINSOCKET
+ errno = WSAGetLastError ();
+ #endif
if (errno == EBADF)
fd_ebadf (EV_A);
}
#if EV_SELECT_USE_FD_SET
-# if EV_SELECT_USE_WIN32_HANDLES
- for (word = 0; word < anfdmax; ++word)
- {
- if (!anfd [word].events)
+
+ {
+ int fd;
+
+ for (fd = 0; fd < anfdmax; ++fd)
+ if (anfds [fd].events)
{
- int fd = _get_osfhandle (word);
+ int events = 0;
+ #if EV_SELECT_IS_WINSOCKET
+ SOCKET handle = anfds [fd].handle;
+ #else
+ int handle = fd;
+ #endif
+
+ if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
+ if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
+
+ if (events)
+ fd_event (EV_A_ fd, events);
+ }
+ }
- if (fd >= 0)
+#else
+
+ {
+ int word, bit;
+ for (word = vec_max; word--; )
+ {
+ fd_mask word_r = ((fd_mask *)vec_ro) [word];
+ fd_mask word_w = ((fd_mask *)vec_wo) [word];
+
+ if (word_r || word_w)
+ for (bit = NFDBITS; bit--; )
{
+ fd_mask mask = 1UL << bit;
int events = 0;
- if (FD_ISSET (fd, (struct fd_set *)vec_ro)) events |= EV_READ;
- if (FD_ISSET (fd, (struct fd_set *)vec_wo)) events |= EV_WRITE;
+ events |= word_r & mask ? EV_READ : 0;
+ events |= word_w & mask ? EV_WRITE : 0;
if (events)
- fd_event (EV_A_ word, events);
+ fd_event (EV_A_ word * NFDBITS + bit, events);
}
- }
- }
-# else
- for (word = 0; word < FD_SETSIZE; ++word)
- {
- int events = 0;
- if (FD_ISSET (word, (struct fd_set *)vec_ro)) events |= EV_READ;
- if (FD_ISSET (word, (struct fd_set *)vec_wo)) events |= EV_WRITE;
+ }
+ }
- if (events)
- fd_event (EV_A_ word, events);
- }
-# endif
-#else
- for (word = vec_max; word--; )
- {
- if (((uint32_t *)vec_ro) [word] | ((uint32_t *)vec_wo) [word])
- for (offs = 4; offs--; )
- {
- int idx = word * 4 + offs;
- unsigned char byte_r = vec_ro [idx];
- unsigned char byte_w = vec_wo [idx];
- int bit;
-
- if (byte_r | byte_w)
- for (bit = 8; bit--; )
- {
- int events = 0;
- events |= byte_r & (1 << bit) ? EV_READ : 0;
- events |= byte_w & (1 << bit) ? EV_WRITE : 0;
-
- if (events)
- fd_event (EV_A_ idx * 8 + bit, events);
- }
- }
- }
#endif
}
#if EV_SELECT_USE_FD_SET
vec_max = FD_SETSIZE / 32;
- vec_ri = ev_malloc (sizeof (struct fd_set)); FD_ZERO ((struct fd_set *)vec_ri);
- vec_ro = ev_malloc (sizeof (struct fd_set));
- vec_wi = ev_malloc (sizeof (struct fd_set)); FD_ZERO ((struct fd_set *)vec_wi);
- vec_wo = ev_malloc (sizeof (struct fd_set));
+ vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
+ vec_ro = ev_malloc (sizeof (fd_set));
+ vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
+ vec_wo = ev_malloc (sizeof (fd_set));
#else
vec_max = 0;
vec_ri = 0;
VARx(int, activecnt) /* number of active events */
#if EV_USE_SELECT || EV_GENWRAP
-VARx(unsigned char *, vec_ri)
-VARx(unsigned char *, vec_ro)
-VARx(unsigned char *, vec_wi)
-VARx(unsigned char *, vec_wo)
+VARx(void *, vec_ri)
+VARx(void *, vec_ro)
+VARx(void *, vec_wi)
+VARx(void *, vec_wo)
VARx(int, vec_max)
#endif
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef WIN32
+#ifdef _WIN32
#include <sys/timeb.h>
}
#undef gettimeofday
-#define gettimeofdy(tv,tz) ev_gettimeofday (tv, tz)
+#define gettimeofday(tv,tz) ev_gettimeofday (tv, tz)
#endif
+
revents &= EV_READ | EV_WRITE | EV_TIMEOUT | EV_SIGNAL;
ev->ev_res = revents;
- ev->ev_callback (ev->ev_fd, revents, ev->ev_arg);
+ ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg);
}
static void
{
struct x_once *once = (struct x_once *)arg;
- once->cb (once->fd, revents, once->arg);
+ once->cb (once->fd, (short)revents, once->arg);
free (once);
}