sigtimedwait: if we collect a queued signal via pt_siglist, do not

forget to clear it out of pt_siglist, otherwise we will keep getting
it over and over again.   fixes a problem introduced in rev 1.43.

problem observed with mysqld where sending it a SIGHUP after it has
set an alarm (e.g. due to some package like rt3 using it) caused the
signal handler thread to go into a tight loop (collecting a SIGALRM
[via sigwait() in mysqld.cc] that would not go away due to the above
issue).   mysqld appears to get a SIGHUP when /etc/rc exits, so it
can go into this tight loop after a reboot (but not if you restart
it by hand).   the bad sequence is:
	/etc/rc runs:
		- starts mysqld
		- starts web server with rt3 fastcgi starts
		- fastcgi/rt3 talks to mysqld (causing it to set an alarm)
		- /etc/rc exits, SIGHUP goes to mysqld
		- mysqld catches SIGHUP, signal handler thread gets
			stuck in loop (database continues to operate, slowly).

you can also trigger the problem by sending mysqld a SIGHUP by hand after
you've caused it to set an alarm by connecting to it.
This commit is contained in:
chuck 2006-06-12 16:45:14 +00:00
parent 639e2af40a
commit f4e3e7fe3b

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread_sig.c,v 1.45 2006/04/24 19:00:30 snj Exp $ */
/* $NetBSD: pthread_sig.c,v 1.46 2006/06/12 16:45:14 chuck Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_sig.c,v 1.45 2006/04/24 19:00:30 snj Exp $");
__RCSID("$NetBSD: pthread_sig.c,v 1.46 2006/06/12 16:45:14 chuck Exp $");
/* We're interposing a specific version of the signal interface. */
#define __LIBC12_SOURCE__
@ -326,6 +326,7 @@ sigtimedwait(const sigset_t * __restrict set, siginfo_t * __restrict info,
sig = firstsig(&wset);
if (sig) {
info->si_signo = sig;
__sigdelset14(&self->pt_siglist, sig); /* clear it */
pthread_spinunlock(self, &self->pt_siglock);
pthread__testcancel(self);
return 0;