]> source.dussan.org Git - rspamd.git/commitdiff
* Main process now has 'hard termination time' - maximum time between getting termina...
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 23 Mar 2011 14:42:33 +0000 (17:42 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 23 Mar 2011 14:42:33 +0000 (17:42 +0300)
CMakeLists.txt
config.h.in
src/main.c

index 0abd13d9f47f06cc005ec37b3ee199de61b9944c..6f50b56777596ebc405f5a1f57cc02b314f3b7e6 100644 (file)
@@ -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)
index bb8e80a285ebcfc766748e2671b8fed6288168ec..902fbdee62640f6c0c1f2949f59bf3cdbcc44e8a 100644 (file)
 #cmakedefine HAVE_CLOCK_VIRTUAL  1
 #cmakedefine HAVE_CLOCK_PROCESS_CPUTIME_ID  1
 
+#cmakedefine HAVE_SETITIMER      1
+
 #cmakedefine WITHOUT_PERL        1
 
 #cmakedefine WITH_LUA            1
index 43c0a07e603811a6034b5748b97237b14751d7c1..64357c26494e8fbd6f5a1eef6822500bce18e1cf 100644 (file)
@@ -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);