Bug 18559

Summary: pthread_self and signal handler (SIGPIPE)
Product: Base System Reporter: hwc <hwc>
Component: miscAssignee: Jason Evans <jasone>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description hwc 2000-05-15 10:00:01 UTC
I don't knwow is this a bug....


In the thread before use
   send(...)
I'v use
   signal(SIGPIPE,sig_handler);
In sig_handler,
   fprintf(g_log,"%d\t",pthread_self())

but I found, in sig_handler,
   the thread_self return main's thread_id,
   not the thread that use "send" ...


I'v use this code in linux,
in sig_handler,
   the thread_self return "send" thread id, as I'm assumed..

Is freebsd normal ?
I'v traced 
	/usr/src/lib/libc_r/uthread_sig.c
-rw-r--r--  1 root  wheel  20777   3/22 09:19 uthread_sig.c
when SIGPIPE occurs, in 
   _thread_sig_handler(int sig, int code, ucontext_t * scp)
the 
   _thread_run (global variable, pthread_self?)
is the the "send" thread,
but the
   _thread_sig_handle(sig, scp);
return the main thread

I'v modified some code in _thread_sig_handle,
	/usr/src/lib/libc_r/uthread_sig.c, line 323
	
                if ((_thread_sigact[sig - 1].sa_handler == SIG_IGN) ||
                    (_thread_sigact[sig - 1].sa_handler == SIG_DFL))
                        handler_installed = 0;
                else
                        handler_installed = 1;
/**** my code added begin***/
                if (sig==SIGPIPE && handler_installed==1  &&   !sigismember(&_thread_run->sigmask, sig))
                         signaled_thread = _thread_run;
                else
/**** my code end***/
                for (pthread = TAILQ_FIRST(&_waitingq);
                    pthread != NULL; pthread = pthread_next) {
                        /*
                         * Grab the next thread before possibly destroying
                         * the link entry.
                         */
                        pthread_next = TAILQ_NEXT(pthread, pqe);

                               if (sig==SIGPIPE && handler_installed==1)
                                {
                                    if (!sigismember(&_thread_run->sigmask, sig)) {
                                                signaled_thread = _thread_run;

Seems fine......
I don't know will it produce side effect?
Comment 1 Jason Evans freebsd_committer freebsd_triage 2000-05-15 20:58:34 UTC
Responsible Changed
From-To: freebsd-bugs->jasone

Over to maintainer. 
Comment 2 Daniel Eischen freebsd_committer freebsd_triage 2000-09-04 14:39:29 UTC
State Changed
From-To: open->analyzed

The problem seems to be that the main thread doesn't have SIGPIPE 
masked.  In a threaded program, to ensure signals are delivered to 
the desired thread, you should set the signal mask accordingly. 
POSIX states that threads are selected for signal delivery in the 
following order: 

o Threads in sigwait with the signal in the wait mask 
(signal handler not installed) 
o Threads in sigsuspend with the signal being unblocked 
in the threads mask 

In lieu of finding a thread for one of the above, it is unspecified 
which thread should be selected for signal delivery.  Our threads 
library chooses the first thread it finds with the signal unmasked. 
A properly written program should explicitly set the signal mask 
for threads that want to handle signals.  Please try doing that 
and report back if things are not working as expected.
Comment 3 Jason Evans freebsd_committer freebsd_triage 2000-11-07 02:34:46 UTC
State Changed
From-To: analyzed->closed

No additional feedback after analysis (5 1/2 months ago).