From ead13b04cfb76d2cdcd1588098e31c913d1fc05f Mon Sep 17 00:00:00 2001 From: rbb Date: Wed, 21 Feb 2001 01:15:48 +0000 Subject: Add some functions to APR's thread/processes support to allow a single thread to handle all signal processing. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@61266 13f79535-47bb-0310-9956-ffa450edef68 --- build/apr_threads.m4 | 24 ++++++++++++++++++++++++ include/apr_thread_proc.h | 22 ++++++++++++++++++++++ threadproc/unix/signals.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/build/apr_threads.m4 b/build/apr_threads.m4 index 9a9e2a013..05602eea6 100644 --- a/build/apr_threads.m4 +++ b/build/apr_threads.m4 @@ -156,3 +156,27 @@ else fi ])dnl +AC_DEFUN(APACHE_CHECK_SIGWAIT_ONE_ARG,[ + AC_CACHE_CHECK(whether sigwait takes one argument,ac_cv_sigwait_one_arg,[ + AC_TRY_COMPILE([ +#ifdef __NETBSD__ + /* When using the unproven-pthreads package, we need to pull in this + * header to get a prototype for sigwait(). Else things will fail later + * on. XXX Should probably be fixed in the unproven-pthreads package. + */ +#include +#endif +#include +],[ + sigset_t set; + + sigwait(&set); +],[ + ac_cv_sigwait_one_arg=yes +],[ + ac_cv_sigwait_one_arg=no +])]) + if test "$ac_cv_sigwait_one_arg" = "yes"; then + AC_DEFINE(SIGWAIT_TAKES_ONE_ARG,1,[ ]) + fi +]) diff --git a/include/apr_thread_proc.h b/include/apr_thread_proc.h index a9d6fde34..0b9694985 100644 --- a/include/apr_thread_proc.h +++ b/include/apr_thread_proc.h @@ -584,6 +584,28 @@ APR_DECLARE(apr_status_t) apr_proc_kill(apr_proc_t *proc, int sig); APR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *a, apr_proc_t *pid, enum kill_conditions how); +/** + * Setup the process for a single thread to be used for all signal handling. + * @warn This must be called before any threads are created + * @deffunc apr_status_t apr_setup_signal_thread(void) + */ +APR_DECLARE(apr_status_t) apr_setup_signal_thread(void); + +/** + * Create a thread that will listen for signals. The thread will loop + * forever, calling a provided function whenever it receives a signal. That + * functions should return 1 if the signal has been handled, 0 otherwise. + * @param td The newly created thread + * @param tattr The threadattr to use when creating the thread + * @param signal_handler The function to call when a signal is received + * @param p The pool to use when creating the thread + * @deffunc apr_status_t apr_create_signal_thread(apr_thread_t **td, apr_threadattr_t *tattr, int (*signal_handler)(int signum), apr_pool_t *p) + */ +APR_DECLARE(apr_status_t) apr_create_signal_thread(apr_thread_t **td, + apr_threadattr_t *tattr, + int (*signal_handler)(int signum), + apr_pool_t *p); + #ifdef __cplusplus } #endif diff --git a/threadproc/unix/signals.c b/threadproc/unix/signals.c index 6e5f51159..ee9d9f2b6 100644 --- a/threadproc/unix/signals.c +++ b/threadproc/unix/signals.c @@ -63,6 +63,7 @@ #include "apr_want.h" #include +#include apr_status_t apr_proc_kill(apr_proc_t *proc, int signum) @@ -264,3 +265,49 @@ const char *apr_signal_get_description(int signum) } #endif /* SYS_SIGLIST_DECLARED */ + +static void *signal_thread_func(void *signal_handler) +{ + sigset_t sig_mask; + int (*sig_func)(int signum) = signal_handler; + + /* This thread will be the one responsible for handling signals */ + sigfillset(&sig_mask); + while (1) { + int signal_received; + + apr_sigwait(&sig_mask, &signal_received); + if (sig_func(signal_received) == 1) { + return NULL; + } + } +} + +APR_DECLARE(apr_status_t) apr_setup_signal_thread(void) +{ + sigset_t sig_mask; + int rv; + + /* All threads should mask signals out, accoring to sigwait(2) man page */ + sigfillset(&sig_mask); + +#ifdef SIGPROCMASK_SETS_THREAD_MASK + rv = sigprocmask(SIG_SETMASK, &sig_mask, NULL); +#else + if ((rv = pthread_sigmask(SIG_SETMASK, &sig_mask, NULL)) != 0) { +#ifdef PTHREAD_SETS_ERRNO + rv = errno; +#endif + } +#endif + return rv; +} + +APR_DECLARE(apr_status_t) apr_create_signal_thread(apr_thread_t **td, + apr_threadattr_t *tattr, + int (*signal_handler)(int signum), + apr_pool_t *p) +{ + return apr_thread_create(td, tattr, signal_thread_func, signal_handler, p); +} + -- cgit v1.2.1