I have noticed that sigwait() does not return immediately if called in the following situation: * One of the signals the command is looking for isalready pending. * This signal was send to the entire process rather than to a specific thread. * sigwait() is called from a thread other than the 'main' thread.
Look at the test case below. The function test_sigwait() is first called from the 'main' thread and then from another thread created in main(). This should not make a difference here, but the function shows different behaviour. My interpretation is that sigwait() simply forgets to look for non-thread-specific signals which are already pending at the time when it is called. Regards, Andreas My system is: $ uname -a CYGWIN_NT-6.1-WOW64 zoppo 1.7.17(0.262/5/3) 2012-10-19 14:39 i686 Cygwin Here is an example session (comments preceded by //): $ ./test_case pid: 2396 thread 1 waiting for SIGUSR1 // From another console, first send SIGUSR2 // (which should remain pending), then SIGUSR1: $ kill -SIGUSR2 2396 $ kill -SIGUSR1 2396 // The program catches SIGUSR1 first, then SIGUSR2. // Finally, a second thread starts waiting for SIGUSR1: thread 1 received SIGUSR1 thread 1 waiting for SIGUSR2 thread 1 received SIGUSR2 thread 2 waiting for SIGUSR1 // Now the same again: first SIGUSR2, then SIGUSR1: $ kill -SIGUSR2 2396 $ kill -SIGUSR1 2396 // The program only catches SIGUSR1, // but it blocks waiting for SIGUSR2: thread 2 received SIGUSR1 thread 2 waiting for SIGUSR2 // Send SIGUSR2 again: $ kill -SIGUSR2 2396 // The program exits normally: thread 2 received SIGUSR2 $ ######################################## #include <stdio.h> #include <signal.h> #include <pthread.h> // compile with -lpthread void *test_sigwait(void *arg) { int *threadnr = (int *)arg; int signr; sigset_t sigusr1, sigusr2; sigemptyset(&sigusr1); sigemptyset(&sigusr2); sigaddset(&sigusr1, SIGUSR1); sigaddset(&sigusr2, SIGUSR2); printf("thread %d waiting for SIGUSR1\n", *threadnr); sigwait(&sigusr1, &signr); printf("thread %d received SIGUSR1\n", *threadnr); printf("thread %d waiting for SIGUSR2\n", *threadnr); sigwait(&sigusr2, &signr); printf("thread %d received SIGUSR2\n", *threadnr); } int main() { sigset_t sigmask; sigemptyset(&sigmask); sigaddset(&sigmask, SIGUSR1); sigaddset(&sigmask, SIGUSR2); sigprocmask(SIG_BLOCK, &sigmask, NULL); printf("pid: %d\n", getpid()); int threadnr = 1; test_sigwait(&threadnr); pthread_t thread2; threadnr = 2; pthread_create(&thread2, NULL, test_sigwait, &threadnr); pthread_join(thread2, NULL); return(0); } -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple