IF(HAVE_TIME_H)
LIST(APPEND CMAKE_REQUIRED_INCLUDES time.h)
ENDIF(HAVE_TIME_H)
+IF(HAVE_SYS_TIME_H)
+ LIST(APPEND CMAKE_REQUIRED_INCLUDES sys/time.h)
+ENDIF(HAVE_SYS_TIME_H)
CHECK_FUNCTION_EXISTS(setproctitle HAVE_SETPROCTITLE)
CHECK_FUNCTION_EXISTS(getpagesize HAVE_GETPAGESIZE)
CHECK_FUNCTION_EXISTS(tanhl HAVE_TANHL)
CHECK_FUNCTION_EXISTS(sendfile HAVE_SENDFILE)
CHECK_FUNCTION_EXISTS(mkstemp HAVE_MKSTEMP)
+CHECK_FUNCTION_EXISTS(setitimer HAVE_SETITIMER)
CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
CHECK_SYMBOL_EXISTS(PATH_MAX limits.h HAVE_PATH_MAX)
/* 2 seconds to fork new process in place of dead one */
#define SOFT_FORK_TIME 2
+/* 10 seconds after getting termination signal to terminate all workers with SIGKILL */
+#define HARD_TERMINATION_TIME 10
+
rspamd_hash_t *counters;
return cur;
}
+static void
+set_alarm (guint seconds)
+{
+#ifdef HAVE_SETITIMER
+ static struct itimerval itv;
+
+ itv.it_interval.tv_sec = 0;
+ itv.it_interval.tv_usec = 0;
+ itv.it_value.tv_sec = seconds;
+ itv.it_value.tv_usec = 0;
+
+ if (setitimer (ITIMER_REAL, &itv, NULL) == -1) {
+ msg_err ("set alarm failed: %s", strerror (errno));
+ }
+#else
+ (void)alarm (seconds);
+#endif
+}
+
static void
delay_fork (struct worker_conf *cf)
{
workers_pending = g_list_prepend (workers_pending, cf);
- (void)alarm (SOFT_FORK_TIME);
+ set_alarm (SOFT_FORK_TIME);
}
struct rspamd_worker *w = value;
gint res = 0;
- waitpid (w->pid, &res, 0);
+ if (got_alarm) {
+ got_alarm = 0;
+ /* Set alarm for hard termination */
+ set_alarm (HARD_TERMINATION_TIME);
+ }
+
+ if (waitpid (w->pid, &res, 0) == -1) {
+ if (errno == EINTR) {
+ msg_info ("terminate worker %P with SIGKILL", w->pid);
+ kill (w->pid, SIGKILL);
+ got_alarm = 1;
+ }
+ }
- msg_debug ("%s process %P terminated", process_to_str (w->type), w->pid);
+ msg_info ("%s process %P terminated %s", process_to_str (w->type), w->pid,
+ got_alarm ? "hardly" : "softly");
g_free (w->cf);
g_free (w);
}
}
+ /* Restore some signals */
+ sigemptyset (&signals.sa_mask);
+ sigaddset (&signals.sa_mask, SIGALRM);
+ sigaddset (&signals.sa_mask, SIGINT);
+ sigaddset (&signals.sa_mask, SIGTERM);
+ sigaction (SIGALRM, &signals, NULL);
+ sigaction (SIGTERM, &signals, NULL);
+ sigaction (SIGINT, &signals, NULL);
+ sigprocmask (SIG_UNBLOCK, &signals.sa_mask, NULL);
+ /* Set alarm for hard termination */
+ set_alarm (HARD_TERMINATION_TIME);
/* Wait for workers termination */
g_hash_table_foreach_remove (rspamd->workers, wait_for_workers, NULL);