--- IO-AIO/schmorp.h 2009/07/15 01:36:04 1.5 +++ IO-AIO/schmorp.h 2009/07/17 00:56:54 1.6 @@ -6,6 +6,7 @@ */ #include +#include #ifndef _WIN32 # include @@ -195,12 +196,13 @@ return newRV_noinc ((SV *)cv); } -/** portable pipe/socketpair */ +/*****************************************************************************/ +/* portable pipe/socketpair */ #ifdef USE_SOCKETS_AS_HANDLES -# define S_TO_SOCKET(x) (win32_get_osfhandle (x)) +# define S_TO_HANDLE(x) ((HANDLE)win32_get_osfhandle (x)) #else -# define S_TO_SOCKET(x) (x) +# define S_TO_HANDLE(x) ((HANDLE)x) #endif #ifdef _WIN32 @@ -293,9 +295,9 @@ static int s_fd_blocking (int fd, int blocking) { - blocking = !blocking; + u_long nonblocking = !blocking; - return ioctlsocket (S_TO_SOCKET (fd), FIONBIO, &blocking); + return ioctlsocket ((SOCKET)S_TO_HANDLE (fd), FIONBIO, &nonblocking); } #define s_fd_prepare(fd) s_fd_blocking (fd, 0) @@ -391,12 +393,24 @@ return; epp->sent = 1; + { #ifdef _WIN32 - send (epp->fd [1], epp, 1); + /* perl overrides send with a function that crashes in other threads. + * unfortunately, it overrides it with an argument-less macro, so + * there is no way to force usage of the real send function. + * incompetent windows programmers - is this redundant? + */ + DWORD dummy; + WriteFile (S_TO_HANDLE (epp->fd [1]), (LPCVOID)&dummy, 1, &dummy, 0); #else - static uint64_t counter = 1; - write (epp->fd [1], &counter, epp->len); + static uint64_t counter = 1; + /* some modules accept fd's from outside, support eventfd here */ + if (write (epp->fd [1], &counter, epp->len) < 0 + && errno == EINVAL + && epp->len != 8) + write (epp->fd [1], &counter, (epp->len = 8)); #endif + } } static void @@ -405,7 +419,7 @@ char buf [9]; #ifdef _WIN32 - PerlSock_recv (epp->fd [0], buf, sizeof (buf), 0); + recv (epp->fd [0], buf, sizeof (buf), 0); #else read (epp->fd [0], buf, sizeof (buf)); #endif @@ -427,7 +441,7 @@ if (epp->len) { - if (dup2 (S_TO_SOCKET (epn.fd [0]), S_TO_SOCKET (epp->fd [0])) < 0) + if (dup2 (epn.fd [0], epp->fd [0]) < 0) croak ("unable to dup over old event pipe"); /* should not croak */ if (epp->fd [1] != epp->fd [0]) @@ -448,11 +462,12 @@ { #ifdef _WIN32 fd_set rfd; + int fd = s_epipe_fd (epp); FD_ZERO (&rfd); - FD_SET (s_epipe_fd (epp), &rfd); + FD_SET (fd, &rfd); - return PerlSock_select (s_epipe_fd (epp) + 1, &rfd, 0, 0, 0); + return PerlSock_select (fd + 1, &rfd, 0, 0, 0); #else /* poll is preferable on posix systems */ struct pollfd pfd;