diff --git a/src/iperf_api.h b/src/iperf_api.h index 131314243..2b71613e9 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -475,6 +475,7 @@ enum { IEPTHREADJOIN=152, // Unable to join thread (check perror) IEPTHREADATTRINIT=153, // Unable to initialize thread attribute (check perror) IEPTHREADATTRDESTROY=154, // Unable to destroy thread attribute (check perror) + IEPTHREADSIGMASK=155, // Unable to initialize sub thread signal mask (check perror) /* Stream errors */ IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror) IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror) diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c index 7c22caded..c26bcc27a 100644 --- a/src/iperf_client_api.c +++ b/src/iperf_client_api.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "iperf.h" #include "iperf_api.h" @@ -56,6 +57,23 @@ iperf_client_worker_run(void *s) { struct iperf_stream *sp = (struct iperf_stream *) s; struct iperf_test *test = sp->test; + /* Blocking signal to make sure that signal will be handled by main thread */ + sigset_t set; + sigemptyset(&set); +#ifdef SIGTERM + sigaddset(&set, SIGTERM); +#endif +#ifdef SIGHUP + sigaddset(&set, SIGHUP); +#endif +#ifdef SIGINT + sigaddset(&set, SIGINT); +#endif + if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) { + i_errno = IEPTHREADSIGMASK; + goto cleanup_and_fail; + } + /* Allow this thread to be cancelled even if it's in a syscall */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); diff --git a/src/iperf_error.c b/src/iperf_error.c index ce925a81f..3388d376e 100644 --- a/src/iperf_error.c +++ b/src/iperf_error.c @@ -505,6 +505,9 @@ iperf_strerror(int int_errno) snprintf(errstr, len, "unable to create thread attributes"); perr = 1; break; + case IEPTHREADSIGMASK: + snprintf(errstr, len, "unable to change mask of blocked signals"); + break; case IEPTHREADATTRDESTROY: snprintf(errstr, len, "unable to destroy thread attributes"); perr = 1; diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index b87734fec..9727cdddb 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "iperf.h" #include "iperf_api.h" @@ -69,6 +70,23 @@ iperf_server_worker_run(void *s) { struct iperf_stream *sp = (struct iperf_stream *) s; struct iperf_test *test = sp->test; + /* Blocking signal to make sure that signal will be handled by main thread */ + sigset_t set; + sigemptyset(&set); +#ifdef SIGTERM + sigaddset(&set, SIGTERM); +#endif +#ifdef SIGHUP + sigaddset(&set, SIGHUP); +#endif +#ifdef SIGINT + sigaddset(&set, SIGINT); +#endif + if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) { + i_errno = IEPTHREADSIGMASK; + goto cleanup_and_fail; + } + /* Allow this thread to be cancelled even if it's in a syscall */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);