[Prev] [Contents] [Next]

pthread_sigmask()--Set or Get the Signal Mask

Syntax

#include <pthread.h>
#include <signal.h>
int pthread_sigmask(int how, const sigset_t *set,
                    sigset_t *oset);
Threadsafe: Yes
Signal Safe: Yes

The pthread_sigmask() function examines and/or modifies the signal blocking mask for the current thread.

The signals SIGKILL or SIGSTOP cannot be blocked. Any attempt to use pthread_sigmask() to block these signals is simply ignored, and no error is returned.

SIGFPE, SIGILL, and SIGSEGV signals that are not artificially generated by kill(), pthread_kill() or raise() (that is, were generated by the system as a result of a hardware or software exception) are not blocked.

If there are any pending unblocked signals after pthread_sigmask() has changed the signal mask, at least on of those signals is delivered to the process before pthread_sigmask() returns.

If pthread_sigmask() fails, the thread's signal mask is not changed.

The possible values for how, which are defined in the <sys/signal.h> header file, are as follows:

SIG_BLOCK
Indicates that the set of signals given by set should be blocked, in addition to the set currently being blocked.
SIG_UNBLOCK
Indicates that the set of signals given by set should not be blocked. These signals are removed from the current set of signals being blocked.
SIG_SETMASK
Indicates that the set of signals given by set should replace the old set of signals being blocked.
The set parameter points to a signal set giving the new signals that should be blocked or unblocked (depending on the value of how), or it points to the new signal mask if the value of how was SIG_SETMASK. If set is a NULL pointer, the set of blocked signals is not changed. If set is NULL, the value of how is ignored.

The signal set manipulation functions (sigemptyset(), sigfillset(), sigaddset(), and sigdelset()) must be used to establish the new signal set pointed to by set.

The pthread_sigmask() function determines the current signal set and returns this information in *oset. If set is NULL, oset returns the current set of signals being blocked. When set is not NULL, the set of signals pointed to by oset is the previous set.

Parameters

how
(Input) The way in which the signal set is changed
set
(Input) A pointer to a set of signals to be used to change the currently blocked set. May be NULL.
oset
(Output) A pointer to the space where the previous signal mask is stored. May be NULL.

Authorities and Locks

None.

Return Value

0
pthread_sigmask() was successful.
value
pthread_sigmask() was not successful. value is set to indicate the error condition.

Error Conditions

If pthread_sigmask() was not successful, the error condition returned usually indicates one of the following errors. Under some conditions, the value returned could indicate an error other than those listed here.

[EINVAL]
The value specified for the argument is not correct.
[ENOTSIGINIT]
The process is not enabled for signals.

Related Information

Example

#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include <sys/signal.h>
#include "check.h"

#define NUMTHREADS 3
void sighand(int signo);

void *threadfunc(void *parm)
{
  pthread_t             self = pthread_self();
  pthread_id_np_t       tid;
  int                   rc;

  pthread_getunique_np(&self, &tid);
  printf("Thread 0x%.8x %.8x entered\n", tid);
  errno = 0;
  rc = sleep(30);
  if (rc != 0 && errno == EINTR) {
    printf("Thread 0x%.8x %.8x got a signal delivered to it\n",
           tid);
    return NULL;
  }
  printf("Thread 0x%.8x %.8x didn't get expected results! rc=%d, errno=%d\n",
         tid, rc, errno);
  return NULL;
}

void *threadmasked(void *parm)
{
  pthread_t             self = pthread_self();
  pthread_id_np_t       tid;
  sigset_t              mask;
  int                   rc;

  pthread_getunique_np(&self, &tid);  
  printf("Masked thread 0x%.8x %.8x entered\n", tid);
  
  sigfillset(&mask); /* Mask all allowed signals */
  rc = pthread_sigmask(SIG_BLOCK, &mask, NULL);
  checkResults("pthread_sigmask()\n", rc);
    
  errno = 0;
  rc = sleep(15);
  if (rc != 0) {
    printf("Masked thread 0x%.8x %.8x didn't get expected results! "
           "rc=%d, errno=%d\n",
           tid, rc, errno);
    return NULL;
  }
  printf("Masked thread 0x%.8x %.8x completed masked work\n",
         tid);
  return NULL;
}

int main(int argc, char **argv)
{
  int                     rc;
  int                     i;
  struct sigaction        actions;
  pthread_t               threads[NUMTHREADS];
  pthread_t               maskedthreads[NUMTHREADS];

  printf("Enter Testcase - %s\n", argv[0]);
  
  printf("Set up the alarm handler for the process\n");
  memset(&actions, 0, sizeof(actions));
  sigemptyset(&actions.sa_mask);
  actions.sa_flags = 0;
  actions.sa_handler = sighand;

  rc = sigaction(SIGALRM,&actions,NULL);
  checkResults("sigaction\n", rc);

  printf("Create masked and unmasked threads\n");
  for(i=0; i<NUMTHREADS; ++i) {
    rc = pthread_create(&threads[i], NULL, threadfunc, NULL);
    checkResults("pthread_create()\n", rc);
    
    rc = pthread_create(&maskedthreads[i], NULL, threadmasked, NULL);
    checkResults("pthread_create()\n", rc);
  }

  sleep(3);
  printf("Send a signal to masked and unmasked threads\n");
  for(i=0; i<NUMTHREADS; ++i) {
    rc = pthread_kill(threads[i], SIGALRM);
    checkResults("pthread_kill()\n", rc);
    
    rc = pthread_kill(maskedthreads[i], SIGALRM);
    checkResults("pthread_kill()\n", rc);
  }

  printf("Wait for masked and unmasked threads to complete\n");
  for(i=0; i<NUMTHREADS; ++i) {
    rc = pthread_join(threads[i], NULL);
    checkResults("pthread_join()\n", rc);
    
    rc = pthread_join(maskedthreads[i], NULL);
    checkResults("pthread_join()\n", rc);
  }
  printf("Main completed\n");
  return 0;
}

void sighand(int signo)
{
  pthread_t             self = pthread_self();
  pthread_id_np_t       tid;
  
  pthread_getunique_np(&self, &tid);
  printf("Thread 0x%.8x %.8x in signal handler\n",
         tid);
  return;
}

Output

Thread 0x00000000 0000000d entered
Masked thread 0x00000000 0000000a entered
Thread 0x00000000 00000009 entered
Thread 0x00000000 0000000b entered
Masked thread 0x00000000 0000000e entered
Masked thread 0x00000000 0000000c entered
Send a signal to masked and unmasked threads
Wait for masked and unmasked threads to complete
Thread 0x00000000 00000009 in signal handler
Thread 0x00000000 00000009 got a signal delivered to it
Thread 0x00000000 0000000b in signal handler
Thread 0x00000000 0000000b got a signal delivered to it
Thread 0x00000000 0000000d in signal handler
Thread 0x00000000 0000000d got a signal delivered to it
Masked thread 0x00000000 0000000a completed masked work
Masked thread 0x00000000 0000000e completed masked work
Masked thread 0x00000000 0000000c completed masked work
Main completed



[Prev] [Contents] [Next]
Copyright © 1998, IBM Corporation. All rights reserved.
Comments? Contact
rchthrds@us.ibm.com