From tobez@td.rh.dk  Tue Dec 19 09:56:17 2000
Return-Path: <tobez@td.rh.dk>
Received: from ns1-dmz.rh.dk (gw-ext.rh.dk [130.226.106.3])
	by hub.freebsd.org (Postfix) with ESMTP
	id 2FB6837B400; Tue, 19 Dec 2000 09:56:17 -0800 (PST)
Received: from ns1.int.rh.dk (ns1-108.rh.dk [130.226.108.194])
	by ns1-dmz.rh.dk (Postfix) with ESMTP
	id 01D45567C7; Tue, 19 Dec 2000 18:56:16 +0100 (CET)
Received: from aylee.t-d.rh.dk (aylee.td.rh.dk [172.31.211.70])
	by ns1.int.rh.dk (8.9.3/8.9.3/mailhub-rh-dk-0.1) with ESMTP id SAA69770;
	Tue, 19 Dec 2000 18:56:15 +0100 (CET)
	(envelope-from tobez@td.rh.dk)
Received: (from tobez@localhost)
	by aylee.t-d.rh.dk (8.11.1/8.9.3/aylee-rh-dk-0.1) id eBJHuEv89695;
	Tue, 19 Dec 2000 18:56:14 +0100 (CET)
	(envelope-from tobez)
Message-Id: <200012191756.eBJHuEv89695@aylee.t-d.rh.dk>
Date: Tue, 19 Dec 2000 18:56:14 +0100 (CET)
From: tobez@tobez.org
Sender: tobez@td.rh.dk
Reply-To: tobez@tobez.org
To: FreeBSD-gnats-submit@freebsd.org
Cc: deischen@freebsd.org, jasone@freebsd.org
Subject: libc_r: non-delivery of previously blocked signals
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         23647
>Category:       bin
>Synopsis:       libc_r: non-delivery of previously blocked signals
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 19 10:00:04 PST 2000
>Closed-Date:    Thu Dec 21 20:24:16 PST 2000
>Last-Modified:  Thu Dec 21 20:25:13 PST 2000
>Originator:     Anton Berezin
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
self
>Environment:

Relatively recent 5.0-CURRENT and 4.2-STABLE.

>Description:

In the program below the SIGINT signal should be delivered immediately
after SIGHUP handler returns.  This does not happen on recent -current
and -stable boxes.

The same program compiled with libc works fine.  It also works right on
3.5, 4.1.1 and older -current boxes.

It appears that pending signals are simply discarded in
_thread_sig_handle_pending() after thread_sig_find() being unable to
find the thread to deliver the signal due to the signal being blocked.

>How-To-Repeat:

Run the following program compiled with -pthread.  The expected output
is `:-)', any other output is wrong.

#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

char sequence[64];
int seqi = 0;
int self;

void hupper(int s)
{
   sequence[seqi++] = ':';
   kill(self,SIGINT);
   sleep(2);
   sequence[seqi++] = '-';
}

void inter(int s)
{
   sequence[seqi++] = ')';
}

int main(void)
{
   struct sigaction sa;

   self = getpid();
   bzero(&sa, sizeof(sa));
   sa.sa_handler = hupper;
   sigaddset(&sa.sa_mask, SIGINT);
   sigaction(SIGHUP, &sa, NULL);
   signal(SIGINT, inter);
   kill(self,SIGHUP);
   sleep(1);
   sequence[seqi++] = '\0';
   printf("%s\n", sequence);
   return 0;
}

>Fix:

I am too unfamiliar with uthread code, so I am afraid the fix below a)
slows down _thread_kern_scheduler(); and b) might break some things.
Nevertheless, here is my take:

--- lib/libc_r/uthread/uthread_kern.c.orig	Tue Dec 19 18:19:19 2000
+++ lib/libc_r/uthread/uthread_kern.c	Tue Dec 19 18:28:37 2000
@@ -203,6 +203,11 @@ _thread_kern_scheduler(void)
 		_thread_sig_check_pending(_thread_run);
 	}
 
+	/* Handle any pending signals */
+	_queue_signals = 1;
+	dequeue_signals();
+	_queue_signals = 0;
+
 	/*
 	 * Enter a scheduling loop that finds the next thread that is
 	 * ready to run. This loop completes when there are no more threads
--- lib/libc_r/uthread/uthread_sig.orig	Tue Dec 19 18:19:31 2000
+++ lib/libc_r/uthread/uthread_sig.c	Tue Dec 19 18:26:21 2000
@@ -483,6 +483,14 @@ _thread_sig_handle_pending(void)
 					 */
 					thread_sig_add(pthread, sig,
 					    /*has_args*/ 1);
+				} else {
+					/*
+					 * We do not want to accidentally
+					 * loose the signal, will try to
+					 * handle it at some later time:
+					 */
+					_thread_sigq[i].blocked = 0;
+					_thread_sigq[i].pending = 1;
 				}
 			}
 		}


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: deischen 
State-Changed-When: Thu Dec 21 20:24:16 PST 2000 
State-Changed-Why:  
Fixed has been applied to both -current and -stable. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=23647 
>Unformatted:
