Mail Archives: cygwin/2010/11/16/06:55:33
Hi,
any suggestions? Can anyone confirm the problem (at least for me the behavi=
or is unexpected...)?
Regards,
Manuel
-----Last message-----
Hi,
I have the following problem. When I install a signal handler and unblock t=
he according signal in one thread, system calls in other threads will be in=
terrupted, although the signal is blocked or ignored in those other threads.
Regards,
Manuel
Btw: Thanks Corinna for the ultra fast bugfix last time. I just didn't want=
 to spam the list with this one line ;)
-------------------------
Basic structure of the test case:
Main:
- Block signal X
- Create thread 1 and 2
- Send signal X to thread 1
Thread 1:
- Install signal handler for signal X
- Unblock signal X
Thread 2:
- [Signal X is still blocked]
- execute an interruptible system call.
After sending signal X to thread 1, the system call in thread 2 will be int=
errupted.
Code of the test case:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
pthread_t DoNotInterruptThreadId1;
pthread_t DoNotInterruptThreadId2;
pthread_t UsesSignalThreadId;
int createThread(void* (*fpStartRoutine)(void* ), void * arg, pthread_t * t=
hreadId )
{
  int ret =3D 0;
  pthread_attr_t attr;
  ret =3D pthread_attr_init( &attr );
  if( ret !=3D 0 )
  {
    pthread_attr_destroy( &attr );
    printf("pthread_attr_init() failed: %s %d\n",sys_errlist[ret],ret);
    return EXIT_FAILURE;
  }
  ret =3D pthread_create(threadId, &attr, fpStartRoutine, arg);
  if( ret !=3D 0 )
  {
    pthread_attr_destroy( &attr );
    printf("pthread_create failed: %s %d\n",sys_errlist[ret],ret);
    return EXIT_FAILURE;
  }
  pthread_attr_destroy( &attr );
  return EXIT_SUCCESS;
}
static void SignalHandler(int signo)
{
  int i =3D 0;
  i++;
  printf("---> Signalhandler called: ");
  switch (signo)
  {
    case SIGUSR1:
    {
      i++;    // Some dummy code.
      printf("SIGUSR1.\n");
      break;
    }
    default: printf("Unknown signal.\n"); break;
  }
}
void * DoNotInterruptThread(void * data)
{
  sigset_t   signal_mask;
  // Check, if the signal is still blocked.
  sigemptyset (&signal_mask);
  if (pthread_sigmask (SIG_BLOCK, NULL, &signal_mask) !=3D 0)
  {
    printf("DoNotInterruptThread: Failed to check signal state.\n");
    return (void*)EXIT_FAILURE;
  }
  if (sigismember(&signal_mask, SIGUSR1) !=3D 1)
  {
    printf("DoNotInterruptThread: SIGUSR1 not blocked.\n");
  }
  else
  {
    printf("DoNotInterruptThread: SIGUSR1 blocked.\n");
  }
  while(1)
  {
   if (sleep(1) !=3D 0)
   {
     printf("DoNotInterruptThread: Sleep failed: %s %d\n",sys_errlist[errno=
],errno);
     return (void*)EXIT_FAILURE;
   }
#if 0
   // Send signal, nothing should happen...
   printf("DoNotInterruptThread: Starting to send SIGUSR1 to self.\n");
   int err =3D 0;
   err =3D pthread_kill(pthread_self(), SIGUSR1);
   if (err !=3D 0)
   {
     printf("DoNotInterruptThread: Sending SIGUSR1 to self...failed.\n");
     return (void*)EXIT_FAILURE;
   }
#endif
  }
}
void * UsesSignalThread(void * data)
{
  sigset_t          signal_mask;
  struct sigaction  sa;
  // Check, if the signal is still blocked.
  sigemptyset (&signal_mask);
  if (pthread_sigmask (SIG_BLOCK, NULL, &signal_mask) !=3D 0)
  {
    printf("UsesSignalThread: Failed to check signal state.\n");
    return (void*)EXIT_FAILURE;
  }
  if (sigismember(&signal_mask, SIGUSR1) !=3D 1)
  {
    printf("UsesSignalThread: SIGUSR1 not blocked (error).\n");
  }
  else
  {
    printf("UsesSignalThread: SIGUSR1 blocked (as expected).\n");
  }
  // Install signal handler
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler =3D SignalHandler;
  sigemptyset(&sa.sa_mask); // Don't block other signals while in the signa=
l handler function
  //sa.sa_flags =3D SA_RESTART; // Restart functions if interrupted by hand=
ler
  if (sigaction(SIGUSR1, &sa, NULL) =3D=3D -1) // NULL =3D don't return the=
 previous installed signal action.
  {
    printf("UsesSignalThread: Failed to install signal handler.\n");
    return (void*)EXIT_FAILURE;
  }
  else
  {
    printf("UsesSignalThread: Successfully installed signal handler.\n");
  }
  // Unblock the signal to be able to enter the signal handler.
  sigemptyset (&signal_mask);
  sigaddset (&signal_mask, SIGUSR1);
  if (pthread_sigmask (SIG_UNBLOCK, &signal_mask, NULL) !=3D 0)
  {
    printf("UsesSignalThread: Failed to unblock signal.\n");
    return (void*)EXIT_FAILURE;
  }
  else
  {
    printf("UsesSignalThread: Successfully unblocked signal.\n");
  }
  // Wait some time.
  if (sleep(2) !=3D 0)
  {
    printf("UsesSignalThread: Sleep failed: %s %d\n",sys_errlist[errno],err=
no);
  }
  return (void*)EXIT_SUCCESS;
}
int main(void)
{
  sigset_t signal_mask;
  puts("Starting Signal test.");
  // Block SIGUSR1 in this thread and thus in all threads created after thi=
s point.
  // Those threads which need the signal will unblock it for themselves.
  sigemptyset (&signal_mask);
  sigaddset (&signal_mask, SIGUSR1);
  if (pthread_sigmask (SIG_BLOCK, &signal_mask, NULL) !=3D 0)
  {
    printf("pthread_sigmask() failed.\n");
    return EXIT_FAILURE;
  }
  // Create 2 two threads which shall not be interrupted by SIGUSR1.
  if (createThread(DoNotInterruptThread, NULL, &DoNotInterruptThreadId1) !=
=3D EXIT_SUCCESS)
  {
    printf("Failed to create DoNotInterrupt 1.\n");
  }
  if (createThread(DoNotInterruptThread, NULL, &DoNotInterruptThreadId2) !=
=3D EXIT_SUCCESS)
  {
    printf("Failed to create DoNotInterrupt 2.\n");
  }
  // Create a thread which uses a signal handler to handle SIGUSR1.
  if (createThread(UsesSignalThread, NULL, &UsesSignalThreadId) !=3D EXIT_S=
UCCESS)
  {
    printf("Failed to create UsesSignalThread.\n");
  }
  sleep(1); // Sleep one second
  printf("Main: Starting to send SIGUSR1.\n");
  int err =3D 0;
  err =3D pthread_kill(UsesSignalThreadId, SIGUSR1);
  if (err !=3D 0)
  {
    printf("Main: Sending SIGUSR1...failed.\n");
    return EXIT_FAILURE;
  }
  printf("Main: Sending SIGUSR1...success.\n");
  pthread_join(UsesSignalThreadId, NULL);
	return EXIT_SUCCESS;
}
--
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
--=20
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
--
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 -