Browse Source

* Main process now has 'hard termination time' - maximum time between getting termination signal and waiting for workers

rspamd-0.5
Vsevolod Stakhov 15 years ago
parent
commit
1d4a64659b
  1. 4
      CMakeLists.txt
  2. 2
      config.h.in
  3. 52
      src/main.c

4
CMakeLists.txt

@ -423,6 +423,9 @@ ENDIF(HAVE_SYS_WAIT_H)
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)
@ -434,6 +437,7 @@ CHECK_FUNCTION_EXISTS(flock HAVE_FLOCK)
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
config.h.in

@ -111,6 +111,8 @@
#cmakedefine HAVE_CLOCK_VIRTUAL 1
#cmakedefine HAVE_CLOCK_PROCESS_CPUTIME_ID 1
#cmakedefine HAVE_SETITIMER 1
#cmakedefine WITHOUT_PERL 1
#cmakedefine WITH_LUA 1

52
src/main.c

@ -51,6 +51,9 @@
/* 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;
@ -406,11 +409,30 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf)
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);
}
@ -581,9 +603,22 @@ wait_for_workers (gpointer key, gpointer value, gpointer unused)
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);
@ -1023,6 +1058,17 @@ main (gint argc, gchar **argv, gchar **env)
}
}
/* 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);

Loading…
Cancel
Save