Package: libc6 Version: 2.2.5-14 Severity: normal Tags: upstream The Single Unix standard requires sem_wait() to be interrupted by a signal delivered to the process - see http://www.opengroup.org/onlinepubs/007908799/xsh/sem_wait.html for details. The glibc implementation of sem_wait(), however, continues to wait on the semaphore after the signal is delivered.
To demonstrate this, I have appended a test program. Compile with -pthread and run it; it will block forever, and be unresponsive to ^C (^\ will kill it). On a Solaris machine, by contrast, it exits successfully, printing nothing, after a short delay (due to the nanosleep() call in child_thread). Code inspection suggests this is still a bug in the latest glibc CVS. -- System Information: Debian Release: testing/unstable Architecture: i386 Kernel: Linux egil 2.4.19 #1 Thu Aug 15 11:07:52 PDT 2002 i686 Locale: LANG=en_US, LC_CTYPE=en_US -- test program: #include <sys/types.h> #include <errno.h> #include <pthread.h> #include <semaphore.h> #include <signal.h> #include <stdio.h> #include <string.h> #include <time.h> #include <unistd.h> static pid_t me; static sem_t sema; static volatile sig_atomic_t sigint_caught = 0; static void * child_thread(void *unused) { sigset_t all; struct timespec ts; /* Block all signals in this thread. */ sigfillset(&all); sigprocmask(SIG_SETMASK, &all, 0); /* Wait a moment to be sure the main thread is blocked on the semaphore. */ ts.tv_sec = 1; ts.tv_nsec = 0; nanosleep(&ts, 0); /* Now feed the main thread a signal. This should interrupt execution of sem_wait(). */ kill(me, SIGINT); return 0; } static void sigint_handler(int unused) { sigint_caught = 1; } int main(void) { sigset_t none; pthread_t child; struct sigaction sa; int status; int semv; /* Initialize... */ me = getpid(); sem_init(&sema, 0, 0); /* semaphore starts out locked */ sigemptyset(&none); sigprocmask(SIG_SETMASK, &none, 0); sa.sa_handler = sigint_handler; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, 0); /* Spawn child thread. */ pthread_create(&child, 0, child_thread, 0); /* Block on semaphore. This should be interrupted by the child sending us a signal. */ status = sem_wait(&sema); /* status should be -1, errno should be EINTR, sigint_caught should be 1, and the semaphore value should still be zero. */ if(status != -1) printf("status = %d != -1\n", status); if(errno != EINTR) printf("errno = %s != EINTR\n", strerror(errno)); if(sigint_caught != 1) printf("sigint_caught = %d != 1\n", sigint_caught); sem_getvalue (&sema, &semv); if(semv != 0) printf("semv = %d != 0\n", semv); /* cleanup */ pthread_join(child, 0); sem_destroy(&sema); return 0; } -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]