• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 #include <pthread.h>
4 #include <signal.h>
5 
6 // Signal handler that does nothing but indicates receipt
signal_handler(int signo)7 static void signal_handler(int signo) {
8     /* Nothing to do */
9 }
10 
11 // Macro to set up SIG signal handler to do nothing
12 #define SETUP_SIG_HANDLER(sig)                                      \
13     do {                                                            \
14         struct sigaction sa;                                        \
15         sa.sa_handler = signal_handler;                             \
16         sa.sa_flags = 0;                                            \
17         sigemptyset(&sa.sa_mask);                                   \
18         sigaction(sig, &sa, NULL);                                  \
19     } while (0)
20 
21 // Macros for signal handling
22 #define ENABLE_SIGNAL(sig)                          \
23     do {                                            \
24         SETUP_SIG_HANDLER(sig);  /* Ensure SIG is handled by empty_signal_handler */ \
25         sigset_t set;                               \
26         sigemptyset(&set);                          \
27         sigaddset(&set, sig);                       \
28         pthread_sigmask(SIG_UNBLOCK, &set, NULL);   \
29     } while (0)
30 
31 #define DISABLE_SIGNAL(sig)                         \
32     do {                                            \
33         sigset_t set;                               \
34         sigemptyset(&set);                          \
35         sigaddset(&set, sig);                       \
36         pthread_sigmask(SIG_BLOCK, &set, NULL);     \
37     } while (0)
38 
39 // Macros to simulate pthread_setcancelstate and pthread_cancel
40 #define PTHREAD_CANCEL_ENABLE 1
41 #define PTHREAD_CANCEL_DISABLE 0
42 
43 #define pthread_setcancelstate(state, oldstate)                             \
44     do {                                                                    \
45         static __thread int thread_cancel_state = PTHREAD_CANCEL_ENABLE;    \
46         if (oldstate != NULL) {                                             \
47             *(int*)oldstate = thread_cancel_state;                          \
48         }                                                                   \
49         if (state == PTHREAD_CANCEL_ENABLE) {                               \
50             thread_cancel_state = PTHREAD_CANCEL_ENABLE;                    \
51             ENABLE_SIGNAL(SIGUSR1);                                         \
52         } else if (state == PTHREAD_CANCEL_DISABLE) {                       \
53             thread_cancel_state = PTHREAD_CANCEL_DISABLE;                   \
54             DISABLE_SIGNAL(SIGUSR1);                                        \
55         }                                                                   \
56     } while (0)
57 
58 #define pthread_cancel(thread)                                              \
59     do {                                                                    \
60         pthread_kill(thread, SIGUSR1);                                      \
61     } while (0)
62