problem with signal handling and threads (fbsd49R)
rmkml
rmkml at wanadoo.fr
Thu Jan 8 03:16:54 PST 2004
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 <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <poll.h>
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 at Wanadoo.fr
More information about the freebsd-hackers
mailing list