1thr_sigsetmask(3C)       Standard C Library Functions       thr_sigsetmask(3C)
2
3
4

NAME

6       thr_sigsetmask - change or examine calling thread's signal mask
7

SYNOPSIS

9       cc -mt [ flag... ] file... [ library... ]
10       #include <thread.h>
11       #include <signal.h>
12
13       int thr_sigsetmask(int how, const sigset_t *set, sigset_t *oset);
14
15

DESCRIPTION

17       The  thr_sigsetmask()  function  changes or examines a calling thread's
18       signal mask. Each thread has its own signal mask. A new thread inherits
19       the calling thread's signal mask and priority; however, pending signals
20       are not inherited. Signals pending for a new thread will be empty.
21
22
23       If the value of the argument set is not  NULL, set points to a  set  of
24       signals  that can modify the currently blocked set. If the value of set
25       is NULL, the value of how is insignificant and the thread's signal mask
26       is  unmodified; thus, thr_sigsetmask() can be used to inquire about the
27       currently blocked signals.
28
29
30       The value of the argument how specifies the method in which the set  is
31       changed and  takes one of the following values:
32
33       SIG_BLOCK      set  corresponds  to a set of signals to block. They are
34                      added to the current signal mask.
35
36
37       SIG_UNBLOCK    set corresponds to a set of signals  to  unblock.  These
38                      signals are deleted from the current signal mask.
39
40
41       SIG_SETMASK    set corresponds to the new signal mask. The current sig‐
42                      nal mask is replaced by set.
43
44
45
46       If the value of oset is not NULL, it points to the location  where  the
47       previous signal mask is stored.
48

RETURN VALUES

50       Upon  successful  completion,  the thr_sigsetmask() function returns 0.
51       Otherwise, it returns a non-zero value.
52

ERRORS

54       The thr_sigsetmask() function will fail if:
55
56       EINVAL    The value of how is not defined and oset is  NULL.
57
58

EXAMPLES

60       Example 1  Create  a  default  thread  that   can  serve  as  a  signal
61       catcher/handler with its own signal mask.
62
63
64       The  following  example  shows how to create a default thread that  can
65       serve as a signal catcher/handler with its own signal  mask.  new  will
66       have a different value from the creator's signal mask.
67
68
69
70       As  POSIX threads and Solaris threads are fully compatible even  within
71       the same process, this example uses pthread_create(3C) if  you  execute
72       a.out 0, or thr_create(3C) if you execute a.out 1.
73
74
75
76       In this example:
77
78
79           o      The  sigemptyset(3C) function initializes a null signal set,
80                  new. The sigaddset(3C) function packs  the  signal,  SIGINT,
81                  into that new set.
82
83           o      Either pthread_sigmask() or thr_sigsetmask() is used to mask
84                  the signal, SIGINT (CTRL-C), from the calling thread,  which
85                  is  main().  The signal is masked to guarantee that only the
86                  new thread will  receive this signal.
87
88           o      pthread_create() or thr_create() creates the signal-handling
89                  thread.
90
91           o      Using  pthread_join(3C)  or  thr_join(3C), main() then waits
92                  for the termination of that signal-handling thread, whose ID
93                  number  is  user_threadID.  Then main() will sleep(3C) for 2
94                  seconds, after which the program terminates.
95
96           o      The signal-handling thread, handler:
97
98               o      Assigns the handler interrupt()  to  handle  the  signal
99                      SIGINT by the call to sigaction(2).
100
101               o      Resets  its own signal set to not block the signal, SIG‐
102                      INT.
103
104               o      Sleeps for 8 seconds to  allow  time  for  the  user  to
105                      deliver the signal SIGINT by pressing the CTRL-C.
106
107         /* cc thisfile.c -lthread -lpthread */
108         #define _REENTRANT    /* basic first 3-lines for threads */
109         #include <pthread.h>
110         #include <thread.h>
111
112         thread_t user_threadID;
113         sigset_t new;
114         void *handler(), interrupt();
115
116         int
117         main( int argc, char *argv[] ){
118            test_argv(argv[1]);
119
120            sigemptyset(&new);
121            sigaddset(&new, SIGINT);
122            switch(*argv[1])  {
123
124              case '0':   /* POSIX */
125                pthread_sigmask(SIG_BLOCK, &new, NULL);
126                pthread_create(&user_threadID, NULL, handler, argv[1]);
127                pthread_join(user_threadID, NULL);
128                break;
129
130              case '1':   /* Solaris */
131                thr_sigsetmask(SIG_BLOCK, &new, NULL);
132                thr_create(NULL, 0, handler, argv[1], 0, &user_threadID);
133                thr_join(user_threadID, NULL, NULL);
134                break;
135         }  /* switch */
136
137            printf("thread handler, # %d, has exited\n",user_threadID);
138                sleep(2);
139                printf("main thread, # %d is done\n", thr_self());
140                return (0)
141         } /* end main */
142
143         struct sigaction act;
144
145         void *
146         handler(char *argv1)
147          {
148                 act.sa_handler = interrupt;
149                 sigaction(SIGINT, &act, NULL);
150                 switch(*argv1){
151                   case '0':     /* POSIX */
152                     pthread_sigmask(SIG_UNBLOCK, &new, NULL);
153                     break;
154                   case '1':   /* Solaris */
155                     thr_sigsetmask(SIG_UNBLOCK, &new, NULL);
156                     break;
157           }
158           printf("\n Press CTRL-C to deliver SIGINT signal to the process\n");
159           sleep(8);  /* give user time to hit CTRL-C */
160           return (NULL)
161         }
162
163         void
164         interrupt(int sig)
165         {
166         printf("thread %d caught signal %d\n", thr_self(), sig);
167         }
168
169         void test_argv(char argv1[])    {
170           if(argv1 == NULL)  {
171              printf("use 0 as arg1 to use thr_create();\n \
172              or use 1 as arg1 to use pthread_create()\n");
173              exit(NULL);
174           }
175         }
176
177
178
179       In  the  last  example,  the  handler thread served as a signal-handler
180       while also taking care of activity of its own (in this case,  sleeping,
181       although  it  could  have  been some other activity). A thread could be
182       completely dedicated to  signal-handling  simply  by  waiting  for  the
183       delivery of a selected signal by blocking with sigwait(2). The two sub‐
184       routines in the previous example,  handler()  and   interrupt(),  could
185       have been replaced with the following routine:
186
187
188         void *
189         handler(void *ignore)
190         { int signal;
191           printf("thread %d waiting for you to press the CTRL-C keys\n",
192                   thr_self());
193           sigwait(&new, &signal);
194           printf("thread %d has received the signal %d \n", thr_self(), signal);
195         }
196         /*pthread_create() and thr_create() would use NULL instead of
197           argv[1] for the arg passed to handler() */
198
199
200
201       In  this  routine, one thread is dedicated to catching and handling the
202       signal specified by the set new, which allows  main() and  all  of  its
203       other  sub-threads, created after pthread_sigmask() or thr_sigsetmask()
204       masked that signal, to continue uninterrupted. Any use  of   sigwait(2)
205       should  be such that all threads block the signals passed to sigwait(2)
206       at all times. Only the thread that calls sigwait() will  get  the  sig‐
207       nals. The call to sigwait(2) takes two arguments.
208
209
210
211       For  this  type  of  background  dedicated  signal-handling  routine, a
212       Solaris daemon thread can be used by passing the argument THR_DAEMON to
213       thr_create().
214
215

ATTRIBUTES

217       See attributes(5) for descriptions of the following attributes:
218
219
220
221
222       ┌─────────────────────────────┬──────────────────────────────┐
223       │      ATTRIBUTE TYPE         │       ATTRIBUTE VALUE        │
224       ├─────────────────────────────┼──────────────────────────────┤
225       │MT-Level                     │MT-Safe and Async-Signal-Safe │
226       └─────────────────────────────┴──────────────────────────────┘
227

SEE ALSO

229       sigaction(2),  sigprocmask(2),  sigwait(2), cond_wait(3C), pthread_can‐
230       cel(3C),   pthread_create(3C),   pthread_join(3C),    pthread_self(3C),
231       sigaddset(3C),      sigemptyset(3C),      sigsetops(3C),     sleep(3C),
232       attributes(5), cancellation(5), standards(5)
233

NOTES

235       It is not possible to block signals that cannot be  caught  or  ignored
236       (see sigaction(2)). It is also not possible to block or unblock SIGCAN‐
237       CEL, as SIGCANCEL is reserved for the implementation  of  POSIX  thread
238       cancellation   (see   pthread_cancel(3C)   and  cancellation(5)).  This
239       restriction is quietly enforced by the standard C library.
240
241
242       Using sigwait(2) in a dedicated thread allows asynchronously  generated
243       signals  to  be managed synchronously; however, sigwait(2) should never
244       be used to manage synchronously generated signals.
245
246
247       Synchronously generated signals are exceptions that are generated by  a
248       thread and are directed at the thread causing the exception. Since sig‐
249       wait() blocks waiting for signals, the blocking thread cannot receive a
250       synchronously generated signal.
251
252
253       Calling  thesigprocmask(2)  function will be the same as if thr_sigset‐
254       mask() or pthread_sigmask() has been called. POSIX leaves the semantics
255       of  the call to sigprocmask(2) unspecified in a multi-threaded process,
256       so programs that care about POSIX portability should not depend on this
257       semantic.
258
259
260       If  a  signal  is  delivered  while a thread is waiting on a  condition
261       variable, the cond_wait(3C) function will be interrupted and  the  han‐
262       dler  will  be executed. The state of the lock protecting the condition
263       variable is undefined while the thread is executing the signal handler.
264
265
266       Signals that are generated synchronously should not be masked. If  such
267       a signal is blocked and delivered, the receiving process is killed.
268
269
270
271SunOS 5.11                        23 Mar 2005               thr_sigsetmask(3C)
Impressum