pthread_sigmask()--Set or Get Signal Mask


  Syntax:
 #include <pthread.h>
 #include <signal.h>
 int pthread_sigmask(int how, const sigset_t *set,
                    sigset_t *oset);
  Service Program Name: QP0WPTHR

  Default Public Authority: *USE

  Threadsafe: Yes

  Signal Safe: Yes

The pthread_sigmask() function examines 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 one of those signals is delivered to the process before pthread_sigmask() returns.

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

The possible values for how, which are defined in the <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 that contains 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 is 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.


Authorities and Locks

None.


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. This value can be NULL
oset
(Output) A pointer to the space where the previous signal mask is stored. This value can be NULL

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

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include <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 did not 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 did not 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

API introduced: V4R3

[ Back to top | Pthread APIs | APIs by category ]