Return-Path: Delivered-To: apmail-apr-cvs-archive@apr.apache.org Received: (qmail 46516 invoked by uid 500); 21 Feb 2001 01:15:50 -0000 Mailing-List: contact cvs-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Reply-To: dev@apr.apache.org Delivered-To: mailing list cvs@apr.apache.org Received: (qmail 46493 invoked by uid 1092); 21 Feb 2001 01:15:49 -0000 Date: 21 Feb 2001 01:15:49 -0000 Message-ID: <20010221011549.46492.qmail@apache.org> From: rbb@apache.org To: apr-cvs@apache.org Subject: cvs commit: apr/threadproc/unix signals.c rbb 01/02/20 17:15:49 Modified: build apr_threads.m4 include apr_thread_proc.h threadproc/unix signals.c Log: Add some functions to APR's thread/processes support to allow a single thread to handle all signal processing. Revision Changes Path 1.3 +24 -0 apr/build/apr_threads.m4 Index: apr_threads.m4 =================================================================== RCS file: /home/cvs/apr/build/apr_threads.m4,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -b -w -u -r1.2 -r1.3 --- apr_threads.m4 2001/02/20 01:53:47 1.2 +++ apr_threads.m4 2001/02/21 01:15:47 1.3 @@ -156,3 +156,27 @@ 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 +]) 1.54 +22 -0 apr/include/apr_thread_proc.h Index: apr_thread_proc.h =================================================================== RCS file: /home/cvs/apr/include/apr_thread_proc.h,v retrieving revision 1.53 retrieving revision 1.54 diff -u -d -b -w -u -r1.53 -r1.54 --- apr_thread_proc.h 2001/02/16 04:15:47 1.53 +++ apr_thread_proc.h 2001/02/21 01:15:48 1.54 @@ -584,6 +584,28 @@ 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 1.19 +47 -0 apr/threadproc/unix/signals.c Index: signals.c =================================================================== RCS file: /home/cvs/apr/threadproc/unix/signals.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -b -w -u -r1.18 -r1.19 --- signals.c 2001/02/16 04:16:19 1.18 +++ signals.c 2001/02/21 01:15:48 1.19 @@ -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 @@ } #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); +} +