X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Message-ID: <50C09142.1090904@mathematik.uni-kl.de> Date: Thu, 06 Dec 2012 13:36:18 +0100 From: =?ISO-8859-1?Q?Andreas_Steenpa=DF?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: sigwait() ignores non-thread-specific pending signals Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com 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 #include #include // 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