From owner-freebsd-hackers@FreeBSD.ORG Thu Jan 8 03:16:54 2004 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6186516A4CE for ; Thu, 8 Jan 2004 03:16:54 -0800 (PST) Received: from mwinf0202.wanadoo.fr (smtp2.wanadoo.fr [193.252.22.29]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8CF2043D62 for ; Thu, 8 Jan 2004 03:16:52 -0800 (PST) (envelope-from rmkml@wanadoo.fr) Received: from [192.168.1.2] (AVelizy-109-1-5-142.w81-48.abo.wanadoo.fr [81.48.102.142]) by mwinf0202.wanadoo.fr (SMTP Server) with ESMTP id 1569AA40020D for ; Thu, 8 Jan 2004 12:16:51 +0100 (CET) Date: Thu, 8 Jan 2004 12:13:17 +0100 (CET) From: rmkml X-X-Sender: rmkml@hp.mgn.net To: freebsd-hackers@freebsd.org Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Subject: problem with signal handling and threads (fbsd49R) X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Jan 2004 11:16:54 -0000 Hi, I've got a problem with signal handling and threads. I've reproduced the problem in a simple code. Description of program: install a signal handler SIGINT. create a thread that do nothing except waiting. main thread use poll to wait forever [ poll(,,-1) ]. user has too crtl-C to interrupt poll after 5 ctrl-C, loop is over and main-thread signals sub-thread to stops. In fact, it appears not to work correctly: after one ctrl-C, user has to press ctrl-C twice before poll returns with errno=EINTR !! If the thread creation is removed from code, the expected behavior is seen : the program works fine. If I replace the poll by sigsuspend() the program works fine too. Is there something wrong with poll function ? Maybe something is wrong in the approach or in the source code ! Any suggstions are wellcome. here is sample C code : _______________________________________ test_thread_signals.c _______________________________________ #define __EXTENSIONS__ #define _REENTRANT /* basic first 3-lines for threads */ #define _GNU_SOURCE #define _THREAD_SAFE #define _POSIX_PTHREAD_SEMANTICS #include #include #include #include #include #include pthread_mutex_t mutex; pthread_t thread; pthread_cond_t condition; void *run(void *argp); static void handler(int); int main(int argc, char **argv) { pthread_attr_t attr; register int i, res; struct pollfd poll_fd; sigset_t set; signal(SIGINT, handler); pthread_attr_init( &attr ); pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED); pthread_mutex_init(&mutex, 0); pthread_cond_init(&condition, 0); /** comment the following line to see the "normal" behavior **/ pthread_create(&thread, &attr, run, 0); pthread_attr_destroy( &attr ); poll_fd.fd = -1; poll_fd.revents=0; poll_fd.events=0; sigemptyset(&set); puts("main: begin loop"); for(i=0; i<5; i++) { /** wait forever **/ res = poll( &poll_fd, (unsigned long)1, -1 ); /** using sigsuspend ... **/ /* res = sigsuspend(&set); */ if( res == -1 && errno==EINTR ) { puts("ctrl-C received"); } printf("res = %d - errno = %d \n", res, errno ); } puts("send sub thread term signal"); pthread_cond_signal(&condition); puts("main end"); return 0; } void *run(void *argp) { puts("begin sub thread and wait"); pthread_mutex_lock(&mutex); pthread_cond_wait(&condition, &mutex); pthread_mutex_unlock(&mutex); puts("end sub thread"); return 0; } void handler(int signo) { } _______________________________________ compilation with $ gcc -g2 -ansi -Wall -o test_thread_signals.o -c test_thread_signals.c $ gcc -o test_thread_signals -pthread test_thread_signals.o here is the results with the original code : $ ./test_thread_signals main: begin loop begin sub thread and wait ^Cctrl-C received res = -1 - errno = 4 ^C^Cctrl-C received res = -1 - errno = 4 ^C^Cctrl-C received res = -1 - errno = 4 ^C^Cctrl-C received res = -1 - errno = 4 ^C^Cctrl-C received res = -1 - errno = 4 send sub thread term signal main end and the trace with no sub thread : $ ./test_thread_signals main: begin loop ^Cctrl-C received res = -1 - errno = 4 ^Cctrl-C received res = -1 - errno = 4 ^Cctrl-C received res = -1 - errno = 4 ^Cctrl-C received res = -1 - errno = 4 ^Cctrl-C received res = -1 - errno = 4 send sub thread term signal main end Regards. Rmkml@Wanadoo.fr