delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2012/12/06/07:36:38

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?= <steenpass AT mathematik DOT uni-kl DOT de>
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
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
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 <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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019