summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-05-31 06:05:29 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-05-31 06:05:29 +0200
commit73f7d5048c0e2ad4817ad208de02adee73938ed0 (patch)
tree1a292a82567eb49d3b0c9a8218d869528a994682
parent6c656c7394bb972e81cd291b0ab126b2e73ce499 (diff)
downloadfastd-73f7d5048c0e2ad4817ad208de02adee73938ed0.tar
fastd-73f7d5048c0e2ad4817ad208de02adee73938ed0.zip
Unblock signals only during poll/epoll wait
If signals are normally blocked, we can avoid a lot of EINTR handling.
-rw-r--r--src/fastd.c10
-rw-r--r--src/poll.c16
-rw-r--r--src/shell.c25
3 files changed, 23 insertions, 28 deletions
diff --git a/src/fastd.c b/src/fastd.c
index fc98ef5..c129a3c 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -96,6 +96,10 @@ static void on_sigchld(int signo UNUSED) {
static void init_signals(void) {
struct sigaction action;
+ sigset_t set, oldset;
+ sigfillset(&set);
+ pthread_sigmask(SIG_SETMASK, &set, &oldset);
+
action.sa_flags = 0;
sigemptyset(&action.sa_mask);
@@ -629,10 +633,6 @@ static inline void reap_zombies(void) {
/** The \em real signal handlers */
static inline void handle_signals(void) {
- sigset_t set, oldset;
- sigfillset(&set);
- pthread_sigmask(SIG_SETMASK, &set, &oldset);
-
if (sighup) {
sighup = false;
@@ -651,8 +651,6 @@ static inline void handle_signals(void) {
sigchld = false;
reap_zombies();
}
-
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
}
diff --git a/src/poll.c b/src/poll.c
index a2d206b..f05a345 100644
--- a/src/poll.c
+++ b/src/poll.c
@@ -34,6 +34,10 @@
#include "async.h"
#include "peer.h"
+#include <pthread.h>
+#include <signal.h>
+
+
#ifdef USE_EPOLL
#include <sys/epoll.h>
@@ -129,6 +133,10 @@ void fastd_poll_handle(void) {
if (timeout < 0 || timeout > maintenance_timeout)
timeout = maintenance_timeout;
+ sigset_t set, oldset;
+ sigemptyset(&set);
+ pthread_sigmask(SIG_SETMASK, &set, &oldset);
+
struct epoll_event events[16];
int ret = epoll_wait(ctx.epoll_fd, events, 16, timeout);
if (ret < 0) {
@@ -138,6 +146,8 @@ void fastd_poll_handle(void) {
exit_errno("epoll_wait");
}
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+
fastd_update_time();
size_t i;
@@ -243,6 +253,10 @@ void fastd_poll_handle(void) {
if (VECTOR_LEN(ctx.pollfds) != 2 + ctx.n_socks + VECTOR_LEN(ctx.peers))
exit_bug("fd count mismatch");
+ sigset_t set, oldset;
+ sigemptyset(&set);
+ pthread_sigmask(SIG_SETMASK, &set, &oldset);
+
int ret = poll(VECTOR_DATA(ctx.pollfds), VECTOR_LEN(ctx.pollfds), timeout);
if (ret < 0) {
if (errno == EINTR)
@@ -251,6 +265,8 @@ void fastd_poll_handle(void) {
exit_errno("poll");
}
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+
fastd_update_time();
if (VECTOR_INDEX(ctx.pollfds, 0).revents & POLLIN)
diff --git a/src/shell.c b/src/shell.c
index c161a9e..076c4c8 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -138,11 +138,10 @@ static bool shell_command_do_exec(const fastd_shell_command_t *command, const fa
shell_command_setenv(parent, env);
- /* unblock SIGCHLD */
+ /* unblock signals */
sigset_t set;
sigemptyset(&set);
- sigaddset(&set, SIGCHLD);
- pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+ pthread_sigmask(SIG_SETMASK, &set, NULL);
execl("/bin/sh", "sh", "-c", command->command, (char*)NULL);
_exit(127);
@@ -157,23 +156,13 @@ bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const f
if (!fastd_shell_command_isset(command))
return true;
- /* block SIGCHLD */
- sigset_t set, oldset;
- sigemptyset(&set);
- sigaddset(&set, SIGCHLD);
- pthread_sigmask(SIG_BLOCK, &set, &oldset);
-
pid_t pid;
- if (!shell_command_do_exec(command, env, &pid)) {
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ if (!shell_command_do_exec(command, env, &pid))
return false;
- }
int status;
pid_t err = waitpid(pid, &status, 0);
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
-
if (err <= 0) {
pr_error_errno("fastd_shell_command_exec_sync: waitpid");
return false;
@@ -199,17 +188,9 @@ bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const f
on SIGCHLD.
*/
static void shell_command_exec_async(const fastd_shell_command_t *command, const fastd_shell_env_t *env) {
- /* block SIGCHLD */
- sigset_t set, oldset;
- sigemptyset(&set);
- sigaddset(&set, SIGCHLD);
- pthread_sigmask(SIG_BLOCK, &set, &oldset);
-
pid_t pid;
if (shell_command_do_exec(command, env, &pid))
VECTOR_ADD(ctx.async_pids, pid);
-
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
}
/** Executes a shell command */