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>
