Async-Interrupt
view release on metacpan or search on metacpan
# define eventfd(initval,flags) -1
# endif
#endif
typedef struct {
int fd[2]; /* read, write fd, might be equal */
int len; /* write length (1 pipe/socket, 8 eventfd) */
} s_epipe;
static int
s_epipe_new (s_epipe *epp)
{
s_epipe ep;
ep.fd [0] = ep.fd [1] = eventfd (0, 0);
if (ep.fd [0] >= 0)
{
s_fd_prepare (ep.fd [0]);
ep.len = 8;
}
else
{
if (s_pipe (ep.fd))
return -1;
if (s_fd_prepare (ep.fd [0])
|| s_fd_prepare (ep.fd [1]))
{
dTHX;
close (ep.fd [0]);
close (ep.fd [1]);
return -1;
}
ep.len = 1;
}
*epp = ep;
return 0;
}
static void
s_epipe_destroy (s_epipe *epp)
{
dTHX;
close (epp->fd [0]);
if (epp->fd [1] != epp->fd [0])
close (epp->fd [1]);
epp->len = 0;
}
static void
s_epipe_signal (s_epipe *epp)
{
#ifdef _WIN32
/* 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;
/* 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
s_epipe_drain (s_epipe *epp)
{
dTHX;
char buf [9];
#ifdef _WIN32
recv (epp->fd [0], buf, sizeof (buf), 0);
#else
read (epp->fd [0], buf, sizeof (buf));
#endif
}
/* like new, but dups over old */
static int
s_epipe_renew (s_epipe *epp)
{
dTHX;
s_epipe epn;
if (epp->fd [1] != epp->fd [0])
close (epp->fd [1]);
if (s_epipe_new (&epn))
return -1;
if (epp->len)
{
if (dup2 (epn.fd [0], epp->fd [0]) < 0)
croak ("unable to dup over old event pipe"); /* should not croak */
close (epn.fd [0]);
if (epn.fd [0] == epn.fd [1])
epn.fd [1] = epp->fd [0];
epn.fd [0] = epp->fd [0];
}
*epp = epn;
return 0;
}
( run in 0.568 second using v1.01-cache-2.11-cpan-39bf76dae61 )