mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 20:41:27 -04:00
r15217@catbus: nickm | 2007-09-20 14:04:32 -0400
Fix win32 signals: teach win32 that we have per-base signal queues; teach signal.c that not everybody has sigaction(). svn:r442
This commit is contained in:
parent
250071830a
commit
f0e06d75e5
@ -52,7 +52,9 @@
|
|||||||
|
|
||||||
extern struct event_list timequeue;
|
extern struct event_list timequeue;
|
||||||
extern struct event_list addqueue;
|
extern struct event_list addqueue;
|
||||||
|
#if 0
|
||||||
extern struct event_list signalqueue;
|
extern struct event_list signalqueue;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct win_fd_set {
|
struct win_fd_set {
|
||||||
u_int fd_count;
|
u_int fd_count;
|
||||||
@ -64,10 +66,12 @@ volatile sig_atomic_t signal_caught = 0;
|
|||||||
/* MSDN says this is required to handle SIGFPE */
|
/* MSDN says this is required to handle SIGFPE */
|
||||||
volatile double SIGFPE_REQ = 0.0f;
|
volatile double SIGFPE_REQ = 0.0f;
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void signal_handler(int sig);
|
static void signal_handler(int sig);
|
||||||
|
|
||||||
void signal_process(void);
|
void signal_process(void);
|
||||||
int signal_recalc(void);
|
int signal_recalc(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct win32op {
|
struct win32op {
|
||||||
int fd_setsz;
|
int fd_setsz;
|
||||||
@ -193,6 +197,8 @@ win32_init(struct event_base *_base)
|
|||||||
winop->readset_out->fd_count = winop->writeset_out->fd_count
|
winop->readset_out->fd_count = winop->writeset_out->fd_count
|
||||||
= winop->exset_out->fd_count = 0;
|
= winop->exset_out->fd_count = 0;
|
||||||
|
|
||||||
|
evsignal_init(_base);
|
||||||
|
|
||||||
return (winop);
|
return (winop);
|
||||||
err:
|
err:
|
||||||
XFREE(winop->readset_in);
|
XFREE(winop->readset_in);
|
||||||
@ -208,7 +214,10 @@ win32_init(struct event_base *_base)
|
|||||||
int
|
int
|
||||||
win32_recalc(struct event_base *base, void *arg, int max)
|
win32_recalc(struct event_base *base, void *arg, int max)
|
||||||
{
|
{
|
||||||
return (signal_recalc());
|
#if 0
|
||||||
|
return (evsignal_recalc());
|
||||||
|
#endif
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -218,13 +227,7 @@ win32_insert(void *op, struct event *ev)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (ev->ev_events & EV_SIGNAL) {
|
if (ev->ev_events & EV_SIGNAL) {
|
||||||
if (ev->ev_events & (EV_READ|EV_WRITE))
|
return (evsignal_add(ev));
|
||||||
event_errx(1, "%s: EV_SIGNAL incompatible use",
|
|
||||||
__func__);
|
|
||||||
if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
if (!(ev->ev_events & (EV_READ|EV_WRITE)))
|
if (!(ev->ev_events & (EV_READ|EV_WRITE)))
|
||||||
return (0);
|
return (0);
|
||||||
@ -265,7 +268,7 @@ win32_del(void *op, struct event *ev)
|
|||||||
int i, found;
|
int i, found;
|
||||||
|
|
||||||
if (ev->ev_events & EV_SIGNAL)
|
if (ev->ev_events & EV_SIGNAL)
|
||||||
return ((int)signal(EVENT_SIGNAL(ev), SIG_IGN));
|
return (evsignal_del(ev));
|
||||||
|
|
||||||
found = -1;
|
found = -1;
|
||||||
for (i=0;i<win32op->n_events;++i) {
|
for (i=0;i<win32op->n_events;++i) {
|
||||||
@ -330,7 +333,7 @@ win32_dispatch(struct event_base *base, void *op,
|
|||||||
if (!fd_count) {
|
if (!fd_count) {
|
||||||
/* Windows doesn't like you to call select() with no sockets */
|
/* Windows doesn't like you to call select() with no sockets */
|
||||||
Sleep(timeval_to_ms(tv));
|
Sleep(timeval_to_ms(tv));
|
||||||
signal_process();
|
evsignal_process(base);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,8 +345,10 @@ win32_dispatch(struct event_base *base, void *op,
|
|||||||
event_debug(("%s: select returned %d", __func__, res));
|
event_debug(("%s: select returned %d", __func__, res));
|
||||||
|
|
||||||
if(res <= 0) {
|
if(res <= 0) {
|
||||||
signal_process();
|
evsignal_process(base);
|
||||||
return res;
|
return res;
|
||||||
|
} else if (base->sig.evsignal_caught) {
|
||||||
|
evsignal_process(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<win32op->n_events;++i) {
|
for (i=0;i<win32op->n_events;++i) {
|
||||||
@ -369,8 +374,10 @@ win32_dispatch(struct event_base *base, void *op,
|
|||||||
event_active(ev,got,1);
|
event_active(ev,got,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (signal_recalc() == -1)
|
if (signal_recalc() == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -380,6 +387,7 @@ win32_dealloc(struct event_base *_base, void *arg)
|
|||||||
{
|
{
|
||||||
struct win32op *win32op = arg;
|
struct win32op *win32op = arg;
|
||||||
|
|
||||||
|
evsignal_dealloc(_base);
|
||||||
if (win32op->readset_in)
|
if (win32op->readset_in)
|
||||||
free(win32op->readset_in);
|
free(win32op->readset_in);
|
||||||
if (win32op->writeset_in)
|
if (win32op->writeset_in)
|
||||||
@ -397,6 +405,7 @@ win32_dealloc(struct event_base *_base, void *arg)
|
|||||||
free(win32op);
|
free(win32op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void
|
static void
|
||||||
signal_handler(int sig)
|
signal_handler(int sig)
|
||||||
{
|
{
|
||||||
@ -435,3 +444,5 @@ signal_process(void)
|
|||||||
memset(evsigcaught, 0, sizeof(evsigcaught));
|
memset(evsigcaught, 0, sizeof(evsigcaught));
|
||||||
signal_caught = 0;
|
signal_caught = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ AC_C_INLINE
|
|||||||
AC_HEADER_TIME
|
AC_HEADER_TIME
|
||||||
|
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop)
|
AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop signal sigaction)
|
||||||
|
|
||||||
if test "x$ac_cv_func_clock_gettime" = "xyes"; then
|
if test "x$ac_cv_func_clock_gettime" = "xyes"; then
|
||||||
AC_DEFINE(DNS_USE_CPU_CLOCK_FOR_ID, 1, [Define if clock_gettime is available in libc])
|
AC_DEFINE(DNS_USE_CPU_CLOCK_FOR_ID, 1, [Define if clock_gettime is available in libc])
|
||||||
@ -333,6 +333,12 @@ if test "x$haveeventports" = "xyes" ; then
|
|||||||
AC_LIBOBJ(evport)
|
AC_LIBOBJ(evport)
|
||||||
needsignal=yes
|
needsignal=yes
|
||||||
fi
|
fi
|
||||||
|
if test "x$bwin32" = "xtrue"; then
|
||||||
|
needsignal=yes
|
||||||
|
fi
|
||||||
|
if test "x$bwin32" = "xtrue"; then
|
||||||
|
needsignal=yes
|
||||||
|
fi
|
||||||
if test "x$needsignal" = "xyes" ; then
|
if test "x$needsignal" = "xyes" ; then
|
||||||
AC_LIBOBJ(signal)
|
AC_LIBOBJ(signal)
|
||||||
fi
|
fi
|
||||||
|
37
signal.c
37
signal.c
@ -30,6 +30,12 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/tree.h>
|
#include <sys/tree.h>
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
@ -38,7 +44,9 @@
|
|||||||
#include <sys/_time.h>
|
#include <sys/_time.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -53,6 +61,7 @@
|
|||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "event-internal.h"
|
#include "event-internal.h"
|
||||||
#include "evsignal.h"
|
#include "evsignal.h"
|
||||||
|
#include "evutil.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
struct event_base *evsignal_base = NULL;
|
struct event_base *evsignal_base = NULL;
|
||||||
@ -67,7 +76,7 @@ evsignal_cb(int fd, short what, void *arg)
|
|||||||
struct event *ev = arg;
|
struct event *ev = arg;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
n = read(fd, signals, sizeof(signals));
|
n = recv(fd, signals, sizeof(signals), 0);
|
||||||
if (n == -1)
|
if (n == -1)
|
||||||
event_err(1, "%s: read", __func__);
|
event_err(1, "%s: read", __func__);
|
||||||
event_add(ev, NULL);
|
event_add(ev, NULL);
|
||||||
@ -90,7 +99,7 @@ evsignal_init(struct event_base *base)
|
|||||||
* pair to wake up our event loop. The event loop then scans for
|
* pair to wake up our event loop. The event loop then scans for
|
||||||
* signals that got delivered.
|
* signals that got delivered.
|
||||||
*/
|
*/
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
|
if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
|
||||||
event_err(1, "%s: socketpair", __func__);
|
event_err(1, "%s: socketpair", __func__);
|
||||||
|
|
||||||
FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
|
FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
|
||||||
@ -98,7 +107,7 @@ evsignal_init(struct event_base *base)
|
|||||||
base->sig.evsignal_caught = 0;
|
base->sig.evsignal_caught = 0;
|
||||||
memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG);
|
memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG);
|
||||||
|
|
||||||
fcntl(base->sig.ev_signal_pair[0], F_SETFL, O_NONBLOCK);
|
evutil_make_socket_nonblocking(base->sig.ev_signal_pair[0]);
|
||||||
|
|
||||||
event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1], EV_READ,
|
event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1], EV_READ,
|
||||||
evsignal_cb, &base->sig.ev_signal);
|
evsignal_cb, &base->sig.ev_signal);
|
||||||
@ -110,13 +119,16 @@ int
|
|||||||
evsignal_add(struct event *ev)
|
evsignal_add(struct event *ev)
|
||||||
{
|
{
|
||||||
int evsignal;
|
int evsignal;
|
||||||
|
#ifdef HAVE_SIGACTION
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
#endif
|
||||||
struct event_base *base = ev->ev_base;
|
struct event_base *base = ev->ev_base;
|
||||||
|
|
||||||
if (ev->ev_events & (EV_READ|EV_WRITE))
|
if (ev->ev_events & (EV_READ|EV_WRITE))
|
||||||
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
|
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
|
||||||
evsignal = EVENT_SIGNAL(ev);
|
evsignal = EVENT_SIGNAL(ev);
|
||||||
|
|
||||||
|
#ifdef HAVE_SIGACTION
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
sa.sa_handler = evsignal_handler;
|
sa.sa_handler = evsignal_handler;
|
||||||
sigfillset(&sa.sa_mask);
|
sigfillset(&sa.sa_mask);
|
||||||
@ -126,6 +138,11 @@ evsignal_add(struct event *ev)
|
|||||||
|
|
||||||
if (sigaction(evsignal, &sa, NULL) == -1)
|
if (sigaction(evsignal, &sa, NULL) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
#else
|
||||||
|
evsignal_base = base;
|
||||||
|
if (signal(evsignal, evsignal_handler) == SIG_ERR)
|
||||||
|
return (-1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!base->sig.ev_signal_added) {
|
if (!base->sig.ev_signal_added) {
|
||||||
base->sig.ev_signal_added = 1;
|
base->sig.ev_signal_added = 1;
|
||||||
@ -138,7 +155,11 @@ evsignal_add(struct event *ev)
|
|||||||
int
|
int
|
||||||
evsignal_del(struct event *ev)
|
evsignal_del(struct event *ev)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_SIGACTION
|
||||||
return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
|
return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
|
||||||
|
#else
|
||||||
|
return (signal(EVENT_SIGNAL(ev),SIG_DFL))==SIG_ERR ? -1 : 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -156,8 +177,12 @@ evsignal_handler(int sig)
|
|||||||
evsignal_base->sig.evsigcaught[sig]++;
|
evsignal_base->sig.evsigcaught[sig]++;
|
||||||
evsignal_base->sig.evsignal_caught = 1;
|
evsignal_base->sig.evsignal_caught = 1;
|
||||||
|
|
||||||
|
#ifndef HAVE_SIGACTION
|
||||||
|
signal(sig, evsignal_handler);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Wake up our notification mechanism */
|
/* Wake up our notification mechanism */
|
||||||
write(evsignal_base->sig.ev_signal_pair[0], "a", 1);
|
send(evsignal_base->sig.ev_signal_pair[0], "a", 1, 0);
|
||||||
errno = save_errno;
|
errno = save_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,8 +213,8 @@ evsignal_dealloc(struct event_base *base)
|
|||||||
}
|
}
|
||||||
assert(TAILQ_EMPTY(&base->sig.signalqueue));
|
assert(TAILQ_EMPTY(&base->sig.signalqueue));
|
||||||
|
|
||||||
close(base->sig.ev_signal_pair[0]);
|
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
|
||||||
base->sig.ev_signal_pair[0] = -1;
|
base->sig.ev_signal_pair[0] = -1;
|
||||||
close(base->sig.ev_signal_pair[1]);
|
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]);
|
||||||
base->sig.ev_signal_pair[1] = -1;
|
base->sig.ev_signal_pair[1] = -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user