From eff534794e7f49166094fa9279bc4d51520d62a8 Mon Sep 17 00:00:00 2001 From: Nickolai Zeldovich Date: Tue, 14 Jan 2003 01:20:03 +0000 Subject: [PATCH] Improved signal-thread support for the pthread fileserver, which avoids blocking signals in any thread, to appease Linux's thread signaling semantics. --- src/tviced/Makefile.in | 5 ++- src/util/Makefile.in | 12 +++++++ src/util/softsig.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/softsig.h | 16 +++++++++ src/viced/viced.c | 60 ++++++++++++++++--------------- 5 files changed, 159 insertions(+), 29 deletions(-) create mode 100644 src/util/softsig.c create mode 100644 src/util/softsig.h diff --git a/src/tviced/Makefile.in b/src/tviced/Makefile.in index 456e3b2..f643cf7 100644 --- a/src/tviced/Makefile.in +++ b/src/tviced/Makefile.in @@ -30,7 +30,7 @@ LWPOBJS=lock.o fasttime.o threadname.o LIBACLOBJS=aclprocs.o netprocs.o -UTILOBJS=assert.o uuid.o serverLog.o fileutil.o netutils.o dirpath.o volparse.o flipbase64.o +UTILOBJS=assert.o uuid.o serverLog.o fileutil.o netutils.o dirpath.o volparse.o flipbase64.o softsig.o DIROBJS=buffer.o dir.o salvage.o @@ -85,6 +85,9 @@ netutils.o: ${UTIL}/netutils.c dirpath.o: ${UTIL}/dirpath.c ${CCRULE} +softsig.o: ${UTIL}/softsig.c + ${CCRULE} + lock.o: ${LWP}/lock.c ${CCRULE} diff --git a/src/util/Makefile.in b/src/util/Makefile.in index b263b52..a61efe4 100644 --- a/src/util/Makefile.in +++ b/src/util/Makefile.in @@ -29,6 +29,7 @@ includes = \ ${TOP_INCDIR}/afs/pthread_glock.h \ ${TOP_INCDIR}/afs/afs_atomlist.h \ ${TOP_INCDIR}/afs/afs_lhash.h \ + ${TOP_INCDIR}/afs/softsig.h \ ${TOP_INCDIR}/potpourri.h all: ${includes} \ @@ -143,6 +144,7 @@ install: \ ${DESTDIR}${includedir}/afs/pthread_glock.h \ ${DESTDIR}${includedir}/afs/afs_atomlist.h \ ${DESTDIR}${includedir}/afs/afs_lhash.h \ + ${DESTDIR}${includedir}/afs/softsig.h \ ${DESTDIR}${includedir}/potpourri.h \ ${DESTDIR}${libdir}/afs/util.a \ ${DESTDIR}${libdir}/afs/libafsutil.a \ @@ -193,6 +195,9 @@ ${TOP_INCDIR}/afs/afs_atomlist.h: ${srcdir}/afs_atomlist.h ${TOP_INCDIR}/afs/afs_lhash.h: ${srcdir}/afs_lhash.h ${INSTALL} $? $@ +${TOP_INCDIR}/afs/softsig.h: ${srcdir}/softsig.h + ${INSTALL} $? $@ + ${TOP_INCDIR}/potpourri.h: ${srcdir}/potpourri.h ${INSTALL} $? $@ @@ -249,6 +254,9 @@ ${DESTDIR}${includedir}/afs/afs_atomlist.h: ${srcdir}/afs_atomlist.h ${DESTDIR}${includedir}/afs/afs_lhash.h: ${srcdir}/afs_lhash.h ${INSTALL} $? $@ +${DESTDIR}${includedir}/afs/softsig.h: ${srcdir}/softsig.h + ${INSTALL} $? $@ + ${DESTDIR}${includedir}/potpourri.h: ${srcdir}/potpourri.h ${INSTALL} $? $@ @@ -309,6 +317,9 @@ ${DEST}/include/afs/afs_atomlist.h: ${srcdir}/afs_atomlist.h ${DEST}/include/afs/afs_lhash.h: ${srcdir}/afs_lhash.h ${INSTALL} $? $@ +${DEST}/include/afs/softsig.h: ${srcdir}/softsig.h + ${INSTALL} $? $@ + ${DEST}/include/potpourri.h: ${srcdir}/potpourri.h ${INSTALL} $? $@ @@ -352,6 +363,7 @@ dest: \ ${DEST}/include/afs/pthread_glock.h \ ${DEST}/include/afs/afs_atomlist.h \ ${DEST}/include/afs/afs_lhash.h \ + ${DEST}/include/afs/softsig.h \ ${DEST}/include/potpourri.h \ ${DEST}/lib/afs/util.a \ ${DEST}/lib/afs/libafsutil.a \ diff --git a/src/util/softsig.c b/src/util/softsig.c new file mode 100644 index 0000000..886a61f --- /dev/null +++ b/src/util/softsig.c @@ -0,0 +1,95 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#define _POSIX_PTHREAD_SEMANTICS +#include +#include +#include +#include +#include + +static pthread_t softsig_tid; +static struct { + void (*handler) (int); + int pending; +} softsig_sigs[NSIG]; + +static void * +softsig_thread (void *arg) +{ + sigset_t ss; + + sigemptyset (&ss); + sigaddset (&ss, SIGUSR1); + + while (1) { + void (*h) (int) = NULL; + int i, sigw; + + for (i = 0; i < NSIG; i++) + if (softsig_sigs[i].pending) { + softsig_sigs[i].pending = 0; + h = softsig_sigs[i].handler; + break; + } + + if (i == NSIG) + assert (0 == sigwait (&ss, &sigw)); + else if (h) + h (i); + } +} + +void +softsig_init () +{ + sigset_t ss, os; + + sigemptyset (&ss); + sigaddset (&ss, SIGUSR1); + + /* Set mask right away, so we don't accidentally SIGUSR1 the + * softsig thread and cause an exit (default action). + */ + assert (0 == pthread_sigmask (SIG_BLOCK, &ss, &os)); + assert (0 == pthread_create (&softsig_tid, NULL, &softsig_thread, NULL)); + assert (0 == pthread_sigmask (SIG_SETMASK, &os, NULL)); +} + +static void +softsig_handler (int signo) +{ + softsig_sigs[signo].pending = 1; + pthread_kill (softsig_tid, SIGUSR1); +} + +void +softsig_signal (int signo, void (*handler) (int)) +{ + softsig_sigs[signo].handler = handler; + signal (signo, softsig_handler); +} + +#if defined(TEST) +static void +print_foo (int signo) +{ + printf ("foo, signo = %d, tid = %d\n", signo, pthread_self ()); +} + +int +main () +{ + softsig_init (); + softsig_signal (SIGINT, print_foo); + printf ("main is tid %d\n", pthread_self ()); + while (1) + sleep (60); +} +#endif diff --git a/src/util/softsig.h b/src/util/softsig.h new file mode 100644 index 0000000..53af0d3 --- /dev/null +++ b/src/util/softsig.h @@ -0,0 +1,16 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#ifndef _SOFTSIG_H +#define _SOFTSIG_H + +void softsig_init (); +void softsig_signal (int signo, void (*handler) (int)); + +#endif diff --git a/src/viced/viced.c b/src/viced/viced.c index 52b0290..bc2fdb9 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -85,6 +85,9 @@ RCSID("$Header$"); #endif #include "viced.h" #include "host.h" +#ifdef AFS_PTHREAD_ENV +#include "softsig.h" +#endif #if defined(AFS_SGI_ENV) #include "sys/schedctl.h" #include "sys/lock.h" @@ -235,22 +238,32 @@ int fs_rxstat_userok(struct rx_call *call) static void ResetCheckSignal(void) { -#ifdef AFS_HPUX_ENV - signal(SIGPOLL, CheckSignal_Signal); -#else -#ifdef AFS_NT40_ENV - signal(SIGUSR2, CheckSignal_Signal); + int signo; + +#if defined(AFS_HPUX_ENV) + signo = SIGPOLL; +#elsif defined(AFS_NT40_ENV) + signo = SIGUSR2; #else - signal(SIGXCPU, CheckSignal_Signal); + signo = SIGXCPU; #endif + +#if defined(AFS_PTHREAD_ENV) + softsig_signal(signo, CheckSignal_Signal); +#else + signal(signo, CheckSignal_Signal); #endif } static void ResetCheckDescriptors(void) { #ifndef AFS_NT40_ENV +#if defined(AFS_PTHREAD_ENV) + softsig_signal(SIGTERM, CheckDescriptors_Signal); +#else signal(SIGTERM, CheckDescriptors_Signal); #endif +#endif } @@ -319,21 +332,6 @@ CheckAdminName() } /*CheckAdminName*/ -#ifdef AFS_PTHREAD_ENV -/* A special LWP that will receive signals, to avoid deadlock */ -static void SignalLWP() -{ - sigset_t nsigset; - - sigfillset(&nsigset); - assert(AFS_SET_SIGMASK(SIG_UNBLOCK, &nsigset, NULL) == 0); - - while (1) - sleep(60); -} -#endif - - /* This LWP does things roughly every 5 minutes */ static void FiveMinuteCheckLWP() { @@ -1353,7 +1351,6 @@ main(int argc, char * argv[]) #ifdef AFS_PTHREAD_ENV pthread_t parentPid, serverPid; pthread_attr_t tattr; - sigset_t nsigset; #else /* AFS_PTHREAD_ENV */ PROCESS parentPid, serverPid; #endif /* AFS_PTHREAD_ENV */ @@ -1426,6 +1423,11 @@ main(int argc, char * argv[]) ViceLog(0, ("File server starting\n")); #endif +#if defined(AFS_PTHREAD_ENV) + /* initialize the pthread soft signal handler thread */ + softsig_init(); +#endif + /* install signal handlers for controlling the fileserver process */ ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */ ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */ @@ -1625,10 +1627,6 @@ main(int argc, char * argv[]) #ifdef AFS_PTHREAD_ENV assert(pthread_attr_init(&tattr) == 0); assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0); - /* Block signals in this thread (and children), create a signal thread */ - sigfillset(&nsigset); - assert(AFS_SET_SIGMASK(SIG_BLOCK, &nsigset, NULL) == 0); - assert(pthread_create(&serverPid, &tattr, (void *)SignalLWP, NULL) == 0); assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0); assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0); @@ -1676,8 +1674,14 @@ main(int argc, char * argv[]) FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO)); } - /* Install handler to catch the shutdown signal */ - signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */ + /* Install handler to catch the shutdown signal; + * bosserver assumes SIGQUIT shutdown + */ +#if defined(AFS_PTHREAD_ENV) + softsig_signal(SIGQUIT, ShutDown_Signal); +#else + signal(SIGQUIT, ShutDown_Signal); +#endif ViceLog(0,("File Server started %s", afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)))); -- 1.9.4