Mail Archives: cygwin/2012/12/06/07:36:38
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
- Raw text -