Blame libevent/signal.c

Packit e9ba0d
/*	$OpenBSD: select.c,v 1.2 2002/06/25 15:50:15 mickey Exp $	*/
Packit e9ba0d
Packit e9ba0d
/*
Packit e9ba0d
 * Copyright 2000-2007 Niels Provos <provos@citi.umich.edu>
Packit e9ba0d
 * Copyright 2007-2012 Niels Provos and Nick Mathewson
Packit e9ba0d
 *
Packit e9ba0d
 * Redistribution and use in source and binary forms, with or without
Packit e9ba0d
 * modification, are permitted provided that the following conditions
Packit e9ba0d
 * are met:
Packit e9ba0d
 * 1. Redistributions of source code must retain the above copyright
Packit e9ba0d
 *    notice, this list of conditions and the following disclaimer.
Packit e9ba0d
 * 2. Redistributions in binary form must reproduce the above copyright
Packit e9ba0d
 *    notice, this list of conditions and the following disclaimer in the
Packit e9ba0d
 *    documentation and/or other materials provided with the distribution.
Packit e9ba0d
 * 3. The name of the author may not be used to endorse or promote products
Packit e9ba0d
 *    derived from this software without specific prior written permission.
Packit e9ba0d
 *
Packit e9ba0d
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
Packit e9ba0d
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Packit e9ba0d
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Packit e9ba0d
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit e9ba0d
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Packit e9ba0d
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit e9ba0d
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit e9ba0d
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit e9ba0d
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Packit e9ba0d
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit e9ba0d
 */
Packit e9ba0d
#include "event2/event-config.h"
Packit e9ba0d
Packit e9ba0d
#ifdef WIN32
Packit e9ba0d
#define WIN32_LEAN_AND_MEAN
Packit e9ba0d
#include <winsock2.h>
Packit e9ba0d
#include <windows.h>
Packit e9ba0d
#undef WIN32_LEAN_AND_MEAN
Packit e9ba0d
#endif
Packit e9ba0d
#include <sys/types.h>
Packit e9ba0d
#ifdef _EVENT_HAVE_SYS_TIME_H
Packit e9ba0d
#include <sys/time.h>
Packit e9ba0d
#endif
Packit e9ba0d
#include <sys/queue.h>
Packit e9ba0d
#ifdef _EVENT_HAVE_SYS_SOCKET_H
Packit e9ba0d
#include <sys/socket.h>
Packit e9ba0d
#endif
Packit e9ba0d
#include <signal.h>
Packit e9ba0d
#include <stdio.h>
Packit e9ba0d
#include <stdlib.h>
Packit e9ba0d
#include <string.h>
Packit e9ba0d
#ifdef _EVENT_HAVE_UNISTD_H
Packit e9ba0d
#include <unistd.h>
Packit e9ba0d
#endif
Packit e9ba0d
#include <errno.h>
Packit e9ba0d
#ifdef _EVENT_HAVE_FCNTL_H
Packit e9ba0d
#include <fcntl.h>
Packit e9ba0d
#endif
Packit e9ba0d
Packit e9ba0d
#include "event2/event.h"
Packit e9ba0d
#include "event2/event_struct.h"
Packit e9ba0d
#include "event-internal.h"
Packit e9ba0d
#include "event2/util.h"
Packit e9ba0d
#include "evsignal-internal.h"
Packit e9ba0d
#include "log-internal.h"
Packit e9ba0d
#include "evmap-internal.h"
Packit e9ba0d
#include "evthread-internal.h"
Packit e9ba0d
Packit e9ba0d
/*
Packit e9ba0d
  signal.c
Packit e9ba0d
Packit e9ba0d
  This is the signal-handling implementation we use for backends that don't
Packit e9ba0d
  have a better way to do signal handling.  It uses sigaction() or signal()
Packit e9ba0d
  to set a signal handler, and a socket pair to tell the event base when
Packit e9ba0d
Packit e9ba0d
  Note that I said "the event base" : only one event base can be set up to use
Packit e9ba0d
  this at a time.  For historical reasons and backward compatibility, if you
Packit e9ba0d
  add an event for a signal to event_base A, then add an event for a signal
Packit e9ba0d
  (any signal!) to event_base B, event_base B will get informed about the
Packit e9ba0d
  signal, but event_base A won't.
Packit e9ba0d
Packit e9ba0d
  It would be neat to change this behavior in some future version of Libevent.
Packit e9ba0d
  kqueue already does something far more sensible.  We can make all backends
Packit e9ba0d
  on Linux do a reasonable thing using signalfd.
Packit e9ba0d
*/
Packit e9ba0d
Packit e9ba0d
#ifndef WIN32
Packit e9ba0d
/* Windows wants us to call our signal handlers as __cdecl.  Nobody else
Packit e9ba0d
 * expects you to do anything crazy like this. */
Packit e9ba0d
#define __cdecl
Packit e9ba0d
#endif
Packit e9ba0d
Packit e9ba0d
static int evsig_add(struct event_base *, evutil_socket_t, short, short, void *);
Packit e9ba0d
static int evsig_del(struct event_base *, evutil_socket_t, short, short, void *);
Packit e9ba0d
Packit e9ba0d
static const struct eventop evsigops = {
Packit e9ba0d
	"signal",
Packit e9ba0d
	NULL,
Packit e9ba0d
	evsig_add,
Packit e9ba0d
	evsig_del,
Packit e9ba0d
	NULL,
Packit e9ba0d
	NULL,
Packit e9ba0d
	0, 0, 0
Packit e9ba0d
};
Packit e9ba0d
Packit e9ba0d
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
Packit e9ba0d
/* Lock for evsig_base and evsig_base_n_signals_added fields. */
Packit e9ba0d
static void *evsig_base_lock = NULL;
Packit e9ba0d
#endif
Packit e9ba0d
/* The event base that's currently getting informed about signals. */
Packit e9ba0d
static struct event_base *evsig_base = NULL;
Packit e9ba0d
/* A copy of evsig_base->sigev_n_signals_added. */
Packit e9ba0d
static int evsig_base_n_signals_added = 0;
Packit e9ba0d
static evutil_socket_t evsig_base_fd = -1;
Packit e9ba0d
Packit e9ba0d
static void __cdecl evsig_handler(int sig);
Packit e9ba0d
Packit e9ba0d
#define EVSIGBASE_LOCK() EVLOCK_LOCK(evsig_base_lock, 0)
Packit e9ba0d
#define EVSIGBASE_UNLOCK() EVLOCK_UNLOCK(evsig_base_lock, 0)
Packit e9ba0d
Packit e9ba0d
void
Packit e9ba0d
evsig_set_base(struct event_base *base)
Packit e9ba0d
{
Packit e9ba0d
	EVSIGBASE_LOCK();
Packit e9ba0d
	evsig_base = base;
Packit e9ba0d
	evsig_base_n_signals_added = base->sig.ev_n_signals_added;
Packit e9ba0d
	evsig_base_fd = base->sig.ev_signal_pair[0];
Packit e9ba0d
	EVSIGBASE_UNLOCK();
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
/* Callback for when the signal handler write a byte to our signaling socket */
Packit e9ba0d
static void
Packit e9ba0d
evsig_cb(evutil_socket_t fd, short what, void *arg)
Packit e9ba0d
{
Packit e9ba0d
	static char signals[1024];
Packit e9ba0d
	ev_ssize_t n;
Packit e9ba0d
	int i;
Packit e9ba0d
	int ncaught[NSIG];
Packit e9ba0d
	struct event_base *base;
Packit e9ba0d
Packit e9ba0d
	base = arg;
Packit e9ba0d
Packit e9ba0d
	memset(&ncaught, 0, sizeof(ncaught));
Packit e9ba0d
Packit e9ba0d
	while (1) {
Packit e9ba0d
		n = recv(fd, signals, sizeof(signals), 0);
Packit e9ba0d
		if (n == -1) {
Packit e9ba0d
			int err = evutil_socket_geterror(fd);
Packit e9ba0d
			if (! EVUTIL_ERR_RW_RETRIABLE(err))
Packit e9ba0d
				event_sock_err(1, fd, "%s: recv", __func__);
Packit e9ba0d
			break;
Packit e9ba0d
		} else if (n == 0) {
Packit e9ba0d
			/* XXX warn? */
Packit e9ba0d
			break;
Packit e9ba0d
		}
Packit e9ba0d
		for (i = 0; i < n; ++i) {
Packit e9ba0d
			ev_uint8_t sig = signals[i];
Packit e9ba0d
			if (sig < NSIG)
Packit e9ba0d
				ncaught[sig]++;
Packit e9ba0d
		}
Packit e9ba0d
	}
Packit e9ba0d
Packit e9ba0d
	EVBASE_ACQUIRE_LOCK(base, th_base_lock);
Packit e9ba0d
	for (i = 0; i < NSIG; ++i) {
Packit e9ba0d
		if (ncaught[i])
Packit e9ba0d
			evmap_signal_active(base, i, ncaught[i]);
Packit e9ba0d
	}
Packit e9ba0d
	EVBASE_RELEASE_LOCK(base, th_base_lock);
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
int
Packit e9ba0d
evsig_init(struct event_base *base)
Packit e9ba0d
{
Packit e9ba0d
	/*
Packit e9ba0d
	 * Our signal handler is going to write to one end of the socket
Packit e9ba0d
	 * pair to wake up our event loop.  The event loop then scans for
Packit e9ba0d
	 * signals that got delivered.
Packit e9ba0d
	 */
Packit e9ba0d
	if (evutil_socketpair(
Packit e9ba0d
		    AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1) {
Packit e9ba0d
#ifdef WIN32
Packit e9ba0d
		/* Make this nonfatal on win32, where sometimes people
Packit e9ba0d
		   have localhost firewalled. */
Packit e9ba0d
		event_sock_warn(-1, "%s: socketpair", __func__);
Packit e9ba0d
#else
Packit e9ba0d
		event_sock_err(1, -1, "%s: socketpair", __func__);
Packit e9ba0d
#endif
Packit e9ba0d
		return -1;
Packit e9ba0d
	}
Packit e9ba0d
Packit e9ba0d
	evutil_make_socket_closeonexec(base->sig.ev_signal_pair[0]);
Packit e9ba0d
	evutil_make_socket_closeonexec(base->sig.ev_signal_pair[1]);
Packit e9ba0d
	base->sig.sh_old = NULL;
Packit e9ba0d
	base->sig.sh_old_max = 0;
Packit e9ba0d
Packit e9ba0d
	evutil_make_socket_nonblocking(base->sig.ev_signal_pair[0]);
Packit e9ba0d
	evutil_make_socket_nonblocking(base->sig.ev_signal_pair[1]);
Packit e9ba0d
Packit e9ba0d
	event_assign(&base->sig.ev_signal, base, base->sig.ev_signal_pair[1],
Packit e9ba0d
		EV_READ | EV_PERSIST, evsig_cb, base);
Packit e9ba0d
Packit e9ba0d
	base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;
Packit e9ba0d
	event_priority_set(&base->sig.ev_signal, 0);
Packit e9ba0d
Packit e9ba0d
	base->evsigsel = &evsigops;
Packit e9ba0d
Packit e9ba0d
	return 0;
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
/* Helper: set the signal handler for evsignal to handler in base, so that
Packit e9ba0d
 * we can restore the original handler when we clear the current one. */
Packit e9ba0d
int
Packit e9ba0d
_evsig_set_handler(struct event_base *base,
Packit e9ba0d
    int evsignal, void (__cdecl *handler)(int))
Packit e9ba0d
{
Packit e9ba0d
#ifdef _EVENT_HAVE_SIGACTION
Packit e9ba0d
	struct sigaction sa;
Packit e9ba0d
#else
Packit e9ba0d
	ev_sighandler_t sh;
Packit e9ba0d
#endif
Packit e9ba0d
	struct evsig_info *sig = &base->sig;
Packit e9ba0d
	void *p;
Packit e9ba0d
Packit e9ba0d
	/*
Packit e9ba0d
	 * resize saved signal handler array up to the highest signal number.
Packit e9ba0d
	 * a dynamic array is used to keep footprint on the low side.
Packit e9ba0d
	 */
Packit e9ba0d
	if (evsignal >= sig->sh_old_max) {
Packit e9ba0d
		int new_max = evsignal + 1;
Packit e9ba0d
		event_debug(("%s: evsignal (%d) >= sh_old_max (%d), resizing",
Packit e9ba0d
			    __func__, evsignal, sig->sh_old_max));
Packit e9ba0d
		p = mm_realloc(sig->sh_old, new_max * sizeof(*sig->sh_old));
Packit e9ba0d
		if (p == NULL) {
Packit e9ba0d
			event_warn("realloc");
Packit e9ba0d
			return (-1);
Packit e9ba0d
		}
Packit e9ba0d
Packit e9ba0d
		memset((char *)p + sig->sh_old_max * sizeof(*sig->sh_old),
Packit e9ba0d
		    0, (new_max - sig->sh_old_max) * sizeof(*sig->sh_old));
Packit e9ba0d
Packit e9ba0d
		sig->sh_old_max = new_max;
Packit e9ba0d
		sig->sh_old = p;
Packit e9ba0d
	}
Packit e9ba0d
Packit e9ba0d
	/* allocate space for previous handler out of dynamic array */
Packit e9ba0d
	sig->sh_old[evsignal] = mm_malloc(sizeof *sig->sh_old[evsignal]);
Packit e9ba0d
	if (sig->sh_old[evsignal] == NULL) {
Packit e9ba0d
		event_warn("malloc");
Packit e9ba0d
		return (-1);
Packit e9ba0d
	}
Packit e9ba0d
Packit e9ba0d
	/* save previous handler and setup new handler */
Packit e9ba0d
#ifdef _EVENT_HAVE_SIGACTION
Packit e9ba0d
	memset(&sa, 0, sizeof(sa));
Packit e9ba0d
	sa.sa_handler = handler;
Packit e9ba0d
	sa.sa_flags |= SA_RESTART;
Packit e9ba0d
	sigfillset(&sa.sa_mask);
Packit e9ba0d
Packit e9ba0d
	if (sigaction(evsignal, &sa, sig->sh_old[evsignal]) == -1) {
Packit e9ba0d
		event_warn("sigaction");
Packit e9ba0d
		mm_free(sig->sh_old[evsignal]);
Packit e9ba0d
		sig->sh_old[evsignal] = NULL;
Packit e9ba0d
		return (-1);
Packit e9ba0d
	}
Packit e9ba0d
#else
Packit e9ba0d
	if ((sh = signal(evsignal, handler)) == SIG_ERR) {
Packit e9ba0d
		event_warn("signal");
Packit e9ba0d
		mm_free(sig->sh_old[evsignal]);
Packit e9ba0d
		sig->sh_old[evsignal] = NULL;
Packit e9ba0d
		return (-1);
Packit e9ba0d
	}
Packit e9ba0d
	*sig->sh_old[evsignal] = sh;
Packit e9ba0d
#endif
Packit e9ba0d
Packit e9ba0d
	return (0);
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
static int
Packit e9ba0d
evsig_add(struct event_base *base, evutil_socket_t evsignal, short old, short events, void *p)
Packit e9ba0d
{
Packit e9ba0d
	struct evsig_info *sig = &base->sig;
Packit e9ba0d
	(void)p;
Packit e9ba0d
Packit e9ba0d
	EVUTIL_ASSERT(evsignal >= 0 && evsignal < NSIG);
Packit e9ba0d
Packit e9ba0d
	/* catch signals if they happen quickly */
Packit e9ba0d
	EVSIGBASE_LOCK();
Packit e9ba0d
	if (evsig_base != base && evsig_base_n_signals_added) {
Packit e9ba0d
		event_warnx("Added a signal to event base %p with signals "
Packit e9ba0d
		    "already added to event_base %p.  Only one can have "
Packit e9ba0d
		    "signals at a time with the %s backend.  The base with "
Packit e9ba0d
		    "the most recently added signal or the most recent "
Packit e9ba0d
		    "event_base_loop() call gets preference; do "
Packit e9ba0d
		    "not rely on this behavior in future Libevent versions.",
Packit e9ba0d
		    base, evsig_base, base->evsel->name);
Packit e9ba0d
	}
Packit e9ba0d
	evsig_base = base;
Packit e9ba0d
	evsig_base_n_signals_added = ++sig->ev_n_signals_added;
Packit e9ba0d
	evsig_base_fd = base->sig.ev_signal_pair[0];
Packit e9ba0d
	EVSIGBASE_UNLOCK();
Packit e9ba0d
Packit e9ba0d
	event_debug(("%s: %d: changing signal handler", __func__, (int)evsignal));
Packit e9ba0d
	if (_evsig_set_handler(base, (int)evsignal, evsig_handler) == -1) {
Packit e9ba0d
		goto err;
Packit e9ba0d
	}
Packit e9ba0d
Packit e9ba0d
Packit e9ba0d
	if (!sig->ev_signal_added) {
Packit e9ba0d
		if (event_add(&sig->ev_signal, NULL))
Packit e9ba0d
			goto err;
Packit e9ba0d
		sig->ev_signal_added = 1;
Packit e9ba0d
	}
Packit e9ba0d
Packit e9ba0d
	return (0);
Packit e9ba0d
Packit e9ba0d
err:
Packit e9ba0d
	EVSIGBASE_LOCK();
Packit e9ba0d
	--evsig_base_n_signals_added;
Packit e9ba0d
	--sig->ev_n_signals_added;
Packit e9ba0d
	EVSIGBASE_UNLOCK();
Packit e9ba0d
	return (-1);
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
int
Packit e9ba0d
_evsig_restore_handler(struct event_base *base, int evsignal)
Packit e9ba0d
{
Packit e9ba0d
	int ret = 0;
Packit e9ba0d
	struct evsig_info *sig = &base->sig;
Packit e9ba0d
#ifdef _EVENT_HAVE_SIGACTION
Packit e9ba0d
	struct sigaction *sh;
Packit e9ba0d
#else
Packit e9ba0d
	ev_sighandler_t *sh;
Packit e9ba0d
#endif
Packit e9ba0d
Packit e9ba0d
	/* restore previous handler */
Packit e9ba0d
	sh = sig->sh_old[evsignal];
Packit e9ba0d
	sig->sh_old[evsignal] = NULL;
Packit e9ba0d
#ifdef _EVENT_HAVE_SIGACTION
Packit e9ba0d
	if (sigaction(evsignal, sh, NULL) == -1) {
Packit e9ba0d
		event_warn("sigaction");
Packit e9ba0d
		ret = -1;
Packit e9ba0d
	}
Packit e9ba0d
#else
Packit e9ba0d
	if (signal(evsignal, *sh) == SIG_ERR) {
Packit e9ba0d
		event_warn("signal");
Packit e9ba0d
		ret = -1;
Packit e9ba0d
	}
Packit e9ba0d
#endif
Packit e9ba0d
Packit e9ba0d
	mm_free(sh);
Packit e9ba0d
Packit e9ba0d
	return ret;
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
static int
Packit e9ba0d
evsig_del(struct event_base *base, evutil_socket_t evsignal, short old, short events, void *p)
Packit e9ba0d
{
Packit e9ba0d
	EVUTIL_ASSERT(evsignal >= 0 && evsignal < NSIG);
Packit e9ba0d
Packit e9ba0d
	event_debug(("%s: "EV_SOCK_FMT": restoring signal handler",
Packit e9ba0d
		__func__, EV_SOCK_ARG(evsignal)));
Packit e9ba0d
Packit e9ba0d
	EVSIGBASE_LOCK();
Packit e9ba0d
	--evsig_base_n_signals_added;
Packit e9ba0d
	--base->sig.ev_n_signals_added;
Packit e9ba0d
	EVSIGBASE_UNLOCK();
Packit e9ba0d
Packit e9ba0d
	return (_evsig_restore_handler(base, (int)evsignal));
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
static void __cdecl
Packit e9ba0d
evsig_handler(int sig)
Packit e9ba0d
{
Packit e9ba0d
	int save_errno = errno;
Packit e9ba0d
#ifdef WIN32
Packit e9ba0d
	int socket_errno = EVUTIL_SOCKET_ERROR();
Packit e9ba0d
#endif
Packit e9ba0d
	ev_uint8_t msg;
Packit e9ba0d
Packit e9ba0d
	if (evsig_base == NULL) {
Packit e9ba0d
		event_warnx(
Packit e9ba0d
			"%s: received signal %d, but have no base configured",
Packit e9ba0d
			__func__, sig);
Packit e9ba0d
		return;
Packit e9ba0d
	}
Packit e9ba0d
Packit e9ba0d
#ifndef _EVENT_HAVE_SIGACTION
Packit e9ba0d
	signal(sig, evsig_handler);
Packit e9ba0d
#endif
Packit e9ba0d
Packit e9ba0d
	/* Wake up our notification mechanism */
Packit e9ba0d
	msg = sig;
Packit e9ba0d
	send(evsig_base_fd, (char*)&msg, 1, 0);
Packit e9ba0d
	errno = save_errno;
Packit e9ba0d
#ifdef WIN32
Packit e9ba0d
	EVUTIL_SET_SOCKET_ERROR(socket_errno);
Packit e9ba0d
#endif
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
void
Packit e9ba0d
evsig_dealloc(struct event_base *base)
Packit e9ba0d
{
Packit e9ba0d
	int i = 0;
Packit e9ba0d
	if (base->sig.ev_signal_added) {
Packit e9ba0d
		event_del(&base->sig.ev_signal);
Packit e9ba0d
		base->sig.ev_signal_added = 0;
Packit e9ba0d
	}
Packit e9ba0d
	/* debug event is created in evsig_init/event_assign even when
Packit e9ba0d
	 * ev_signal_added == 0, so unassign is required */
Packit e9ba0d
	event_debug_unassign(&base->sig.ev_signal);
Packit e9ba0d
Packit e9ba0d
	for (i = 0; i < NSIG; ++i) {
Packit e9ba0d
		if (i < base->sig.sh_old_max && base->sig.sh_old[i] != NULL)
Packit e9ba0d
			_evsig_restore_handler(base, i);
Packit e9ba0d
	}
Packit e9ba0d
	EVSIGBASE_LOCK();
Packit e9ba0d
	if (base == evsig_base) {
Packit e9ba0d
		evsig_base = NULL;
Packit e9ba0d
		evsig_base_n_signals_added = 0;
Packit e9ba0d
		evsig_base_fd = -1;
Packit e9ba0d
	}
Packit e9ba0d
	EVSIGBASE_UNLOCK();
Packit e9ba0d
Packit e9ba0d
	if (base->sig.ev_signal_pair[0] != -1) {
Packit e9ba0d
		evutil_closesocket(base->sig.ev_signal_pair[0]);
Packit e9ba0d
		base->sig.ev_signal_pair[0] = -1;
Packit e9ba0d
	}
Packit e9ba0d
	if (base->sig.ev_signal_pair[1] != -1) {
Packit e9ba0d
		evutil_closesocket(base->sig.ev_signal_pair[1]);
Packit e9ba0d
		base->sig.ev_signal_pair[1] = -1;
Packit e9ba0d
	}
Packit e9ba0d
	base->sig.sh_old_max = 0;
Packit e9ba0d
Packit e9ba0d
	/* per index frees are handled in evsig_del() */
Packit e9ba0d
	if (base->sig.sh_old) {
Packit e9ba0d
		mm_free(base->sig.sh_old);
Packit e9ba0d
		base->sig.sh_old = NULL;
Packit e9ba0d
	}
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
Packit e9ba0d
int
Packit e9ba0d
evsig_global_setup_locks_(const int enable_locks)
Packit e9ba0d
{
Packit e9ba0d
	EVTHREAD_SETUP_GLOBAL_LOCK(evsig_base_lock, 0);
Packit e9ba0d
	return 0;
Packit e9ba0d
}
Packit e9ba0d
#endif