Not doing this can result in a situation where all the other application
threads have a signal blocked, and the listener thread, not having it blocked,
lets the signal handler execute. Therefore, in order to be as transparent as
possible to the application, we have to block signals.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
void create_listener(void)
{
int result;
void create_listener(void)
{
int result;
+ sigset_t sig_all_blocked;
+ sigset_t orig_parent_mask;
if(have_listener) {
WARN("not creating listener because we already had one");
return;
}
if(have_listener) {
WARN("not creating listener because we already had one");
return;
}
+ /* A new thread created by pthread_create inherits the signal mask
+ * from the parent. To avoid any signal being received by the
+ * listener thread, we block all signals temporarily in the parent,
+ * while we create the listener thread.
+ */
+
+ sigfillset(&sig_all_blocked);
+
+ result = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_parent_mask);
+ if(result) {
+ PERROR("pthread_sigmask: %s", strerror(result));
+ }
+
result = pthread_create(&listener_thread, NULL, listener_main, NULL);
if(result == -1) {
PERROR("pthread_create");
}
result = pthread_create(&listener_thread, NULL, listener_main, NULL);
if(result == -1) {
PERROR("pthread_create");
}
+ /* Restore original signal mask in parent */
+ result = pthread_sigmask(SIG_SETMASK, &orig_parent_mask, NULL);
+ if(result) {
+ PERROR("pthread_sigmask: %s", strerror(result));
+ }
+