aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-06-06 14:23:25 +0200
committerTobias Brunner <tobias@strongswan.org>2012-06-06 14:23:25 +0200
commitb200fa573b0d2425d84ec0216b074e3dadef443a (patch)
treea0d2a7951ae2e2ab89952b369399d66c6ea7ab69
parent21043198ff2381761564920fda3b9e8985141fe4 (diff)
downloadstrongswan-b200fa573b0d2425d84ec0216b074e3dadef443a.tar.bz2
strongswan-b200fa573b0d2425d84ec0216b074e3dadef443a.tar.xz
starter: Only handle SIGCHLD asynchronously and the rest in pselect(2).
-rw-r--r--src/starter/starter.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/starter/starter.c b/src/starter/starter.c
index 0cec936c3..5322d271e 100644
--- a/src/starter/starter.c
+++ b/src/starter/starter.c
@@ -12,6 +12,7 @@
* for more details.
*/
+#include <sys/select.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
@@ -292,7 +293,7 @@ int main (int argc, char **argv)
int i;
int id = 1;
- struct timeval tv;
+ struct timespec ts;
unsigned long auto_update = 0;
time_t last_reload;
bool no_fork = FALSE;
@@ -494,7 +495,7 @@ int main (int argc, char **argv)
}
/* we handle these signals in the main thread, so we don't want any
- * of the others to catch them. install a handler for fatal signals. */
+ * of the others to catch them */
memset(&action, 0, sizeof(action));
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, SIGHUP);
@@ -506,6 +507,7 @@ int main (int argc, char **argv)
sigaddset(&action.sa_mask, SIGUSR1);
pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
+ /* install a handler for fatal signals */
action.sa_handler = fatal_signal_handler;
sigaction(SIGSEGV, &action, NULL);
sigaction(SIGILL, &action, NULL);
@@ -518,8 +520,7 @@ int main (int argc, char **argv)
lib->settings->get_int(lib->settings, "starter.threads",
DEFAULT_THREADS));
- /* enable signals for main thread and install signal handler */
- pthread_sigmask(SIG_UNBLOCK, &action.sa_mask, NULL);
+ /* install signal handler for main thread */
action.sa_handler = signal_handler;
sigaction(SIGHUP, &action, NULL);
sigaction(SIGINT, &action, NULL);
@@ -529,6 +530,13 @@ int main (int argc, char **argv)
sigaction(SIGCHLD, &action, NULL);
sigaction(SIGUSR1, &action, NULL);
+ /* the only signal we want to receive asynchronously is SIGCHLD */
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGCHLD);
+ pthread_sigmask(SIG_UNBLOCK, &action.sa_mask, NULL);
+ /* the rest is unblocked in pselect() below */
+ sigemptyset(&action.sa_mask);
+
for (;;)
{
/*
@@ -854,15 +862,16 @@ int main (int argc, char **argv)
{
time_t now = time_monotonic(NULL);
- tv.tv_sec = (now < last_reload + auto_update)
- ? (last_reload + auto_update-now) : 0;
- tv.tv_usec = 0;
+ ts.tv_sec = (now < last_reload + auto_update) ?
+ (last_reload + auto_update - now) : 0;
+ ts.tv_nsec = 0;
}
/*
* Wait for something to happen
*/
- if (select(0, NULL, NULL, NULL, auto_update ? &tv : NULL) == 0)
+ if (pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
+ &action.sa_mask) == 0)
{
/* timeout -> auto_update */
_action_ |= FLAG_ACTION_UPDATE;