Skip site navigation (1)Skip section navigation (2)
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>