[Midnightbsd-cvs] src [7475] trunk/lib/libthr/thread: Fix the spurious signal handler call with zero signo in the threaded process.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri Mar 18 20:11:40 EDT 2016


Revision: 7475
          http://svnweb.midnightbsd.org/src/?rev=7475
Author:   laffer1
Date:     2016-03-18 20:11:39 -0400 (Fri, 18 Mar 2016)
Log Message:
-----------
Fix the spurious signal handler call with zero signo in the threaded process.

Obtained from: FreeBSD (rev 258767)

Revision Links:
--------------
    http://svnweb.midnightbsd.org/src/?rev=258767

Modified Paths:
--------------
    trunk/lib/libthr/thread/thr_private.h
    trunk/lib/libthr/thread/thr_sig.c

Modified: trunk/lib/libthr/thread/thr_private.h
===================================================================
--- trunk/lib/libthr/thread/thr_private.h	2016-03-19 00:07:45 UTC (rev 7474)
+++ trunk/lib/libthr/thread/thr_private.h	2016-03-19 00:11:39 UTC (rev 7475)
@@ -26,7 +26,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/9/lib/libthr/thread/thr_private.h 258767 2013-11-30 14:39:56Z kib $
  */
 
 #ifndef _THR_PRIVATE_H
@@ -431,6 +431,9 @@
 	/* the sigaction should be used for deferred signal. */
 	struct sigaction	deferred_sigact;
 
+	/* deferred signal delivery is performed, do not reenter. */
+	int			deferred_run;
+
 	/* Force new thread to exit. */
 	int			force_exit;
 

Modified: trunk/lib/libthr/thread/thr_sig.c
===================================================================
--- trunk/lib/libthr/thread/thr_sig.c	2016-03-19 00:07:45 UTC (rev 7474)
+++ trunk/lib/libthr/thread/thr_sig.c	2016-03-19 00:11:39 UTC (rev 7475)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/9/lib/libthr/thread/thr_sig.c 258767 2013-11-30 14:39:56Z kib $
  */
 
 #include "namespace.h"
@@ -162,6 +162,7 @@
 	act = _thr_sigact[sig-1].sigact;
 	_thr_rwl_unlock(&_thr_sigact[sig-1].lock);
 	errno = err;
+	curthread->deferred_run = 0;
 
 	/*
 	 * if a thread is in critical region, for example it holds low level locks,
@@ -205,9 +206,9 @@
 	curthread->in_sigsuspend = 0;
 
 	/*
-	 * if thread is in deferred cancellation mode, disable cancellation
+	 * If thread is in deferred cancellation mode, disable cancellation
 	 * in signal handler.
-	 * if user signal handler calls a cancellation point function, e.g,
+	 * If user signal handler calls a cancellation point function, e.g,
 	 * it calls write() to write data to file, because write() is a
 	 * cancellation point, the thread is immediately cancelled if 
 	 * cancellation is pending, to avoid this problem while thread is in
@@ -229,7 +230,7 @@
 	 * We have already reset cancellation point flags, so if user's code
 	 * longjmp()s out of its signal handler, wish its jmpbuf was set
 	 * outside of a cancellation point, in most cases, this would be
-	 * true. however, ther is no way to save cancel_enable in jmpbuf,
+	 * true.  However, there is no way to save cancel_enable in jmpbuf,
 	 * so after setjmps() returns once more, the user code may need to
 	 * re-set cancel_enable flag by calling pthread_setcancelstate().
 	 */
@@ -318,33 +319,27 @@
 	ucontext_t *uc;
 	struct sigaction act;
 	siginfo_t info;
+	int uc_len;
 
-	if (__predict_true(curthread->deferred_siginfo.si_signo == 0))
+	if (__predict_true(curthread->deferred_siginfo.si_signo == 0 ||
+	    curthread->deferred_run))
 		return;
 
-#if defined(__amd64__) || defined(__i386__)
-	uc = alloca(__getcontextx_size());
-	__fillcontextx((char *)uc);
-#else
-	ucontext_t ucv;
-	uc = &ucv;
+	curthread->deferred_run = 1;
+	uc_len = __getcontextx_size();
+	uc = alloca(uc_len);
 	getcontext(uc);
-#endif
-	if (curthread->deferred_siginfo.si_signo != 0) {
-		act = curthread->deferred_sigact;
-		uc->uc_sigmask = curthread->deferred_sigmask;
-		memcpy(&info, &curthread->deferred_siginfo, sizeof(siginfo_t));
-		/* remove signal */
-		curthread->deferred_siginfo.si_signo = 0;
-		if (act.sa_flags & SA_RESETHAND) {
-			struct sigaction tact;
-
-			tact = act;
-			tact.sa_handler = SIG_DFL;
-			_sigaction(info.si_signo, &tact, NULL);
-		}
-		handle_signal(&act, info.si_signo, &info, uc);
+	if (curthread->deferred_siginfo.si_signo == 0) {
+		curthread->deferred_run = 0;
+		return;
 	}
+	__fillcontextx2((char *)uc);
+	act = curthread->deferred_sigact;
+	uc->uc_sigmask = curthread->deferred_sigmask;
+	memcpy(&info, &curthread->deferred_siginfo, sizeof(siginfo_t));
+	/* remove signal */
+	curthread->deferred_siginfo.si_signo = 0;
+	handle_signal(&act, info.si_signo, &info, uc);
 }
 
 static void



More information about the Midnightbsd-cvs mailing list