Date: 2 Apr 2000 19:42:29 -0000 From: "Thimble Smith" <tim@mysql.com> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/17757: select returns 0 if pthread_kill'd w/ sig. handler Message-ID: <20000402194229.71778.qmail@threads.polyesthetic.msg>
next in thread | raw e-mail | index | archive | help
>Number: 17757 >Category: kern >Synopsis: select returns 0 if pthread_kill'd w/ sig. handler >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Apr 2 12:50:02 PDT 2000 >Closed-Date: >Last-Modified: >Originator: Thimble Smith >Release: FreeBSD 4.0-STABLE i386 >Organization: MySQL >Environment: This error appears in 3.4-STABLE and 4.0-STABLE, at least. >Description: When a thread installs a signal handler, and then is pthread_kill'd during a select, it returns 0 (as if the select timed out) instead of -1. In addition, errno is not set to EINTR. If a signal handler is not installed, select correctly returns -1 and sets errno to EINTR. I'm not sure if this affects reads and writes or not, yet. >How-To-Repeat: cd /tmp cat <<END_PROG > simple.c #include <errno.h> #include <pthread.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> void *t_body(void *arg); pthread_mutex_t t_lock; pthread_cond_t t_cond; sigset_t set; #define WRITE(x) do { printf(x "\n"); fflush(stdout); } while (0) int main(void) { pthread_t t; WRITE("main: hello"); pthread_mutex_init(&t_lock, NULL); pthread_cond_init(&t_cond, NULL); sigemptyset(&set); sigaddset(&set, SIGUSR1); pthread_mutex_lock(&t_lock); WRITE("main: creating test thread..."); pthread_create(&t, NULL, t_body, NULL); pthread_cond_wait(&t_cond, &t_lock); pthread_mutex_unlock(&t_lock); pthread_sigmask(SIG_BLOCK, &set, NULL); sleep(1); WRITE("main: killing test thread"); pthread_kill(t, SIGUSR1); pthread_exit(NULL); /* NOTREACHED */ exit(EXIT_SUCCESS); } void handle_sigusr1(int sig) { WRITE("handle_sigusr1"); signal(sig, handle_sigusr1); } void * t_body(void *arg) { struct sigaction sact; fd_set fds; int error; WRITE("test: hello"); #ifdef SIG sact.sa_flags = 0; sact.sa_handler = handle_sigusr1; sigaction(SIGUSR1, &sact, NULL); #endif FD_ZERO(&fds); pthread_detach(pthread_self()); pthread_sigmask(SIG_UNBLOCK, &set, NULL); WRITE("test: go ahead, main"); pthread_mutex_lock(&t_lock); pthread_cond_signal(&t_cond); pthread_mutex_unlock(&t_lock); WRITE("test: sleeping..."); error = select(0, &fds, 0, 0, 0); printf("test: select returned %d\n", error); fflush(stdout); if (errno == EINTR) WRITE("test: INTERRUPTED! Yeah!"); else { printf("test: uh-oh (error: %s)\n", strerror(errno)); fflush(stdout); } return NULL; } END_PROG cc -o simple -DSIG simple.c -pthread ./simple cc -o simple simple.c -pthread ./simple >Fix: >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000402194229.71778.qmail>