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 <pthread.h>
+#endif
+#include <signal.h>
+],[
+ 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 <assert.h>
+#include <pthread.h>
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);
+}
+