]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Try to deal with multiple workers terminated
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 15 Aug 2016 10:49:34 +0000 (11:49 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 15 Aug 2016 10:52:07 +0000 (11:52 +0100)
src/rspamd.c

index 9bea4b5c039db967c2725f9df8beb32881e42e8f..5692e315b14461dca6624063eb5a063edf29a90d 100644 (file)
@@ -917,73 +917,74 @@ rspamd_cld_handler (gint signo, short what, gpointer arg)
        /* Turn off locking for logger */
        rspamd_log_nolock (rspamd_main->logger);
 
-       msg_debug_main ("catch SIGCHLD signal, finding terminated worker");
+       msg_debug_main ("catch SIGCHLD signal, finding terminated workers");
        /* Remove dead child form children list */
-       wrk = waitpid (0, &res, 0);
-       if ((cur =
-                                g_hash_table_lookup (rspamd_main->workers,
-                                                GSIZE_TO_POINTER (wrk))) != NULL) {
-               /* Unlink dead process from queue and hash table */
-
-               g_hash_table_remove (rspamd_main->workers, GSIZE_TO_POINTER (
-                               wrk));
-
-               if (WIFEXITED (res) && WEXITSTATUS (res) == 0) {
-                       /* Normal worker termination, do not fork one more */
-                       msg_info_main ("%s process %P terminated normally",
-                                       g_quark_to_string (cur->type),
-                                       cur->pid);
-               }
-               else {
-                       if (WIFSIGNALED (res)) {
+       while ((wrk = waitpid (0, &res, WNOHANG)) > 0) {
+               if ((cur =
+                               g_hash_table_lookup (rspamd_main->workers,
+                                               GSIZE_TO_POINTER (wrk))) != NULL) {
+                       /* Unlink dead process from queue and hash table */
+
+                       g_hash_table_remove (rspamd_main->workers, GSIZE_TO_POINTER (
+                                       wrk));
+
+                       if (WIFEXITED (res) && WEXITSTATUS (res) == 0) {
+                               /* Normal worker termination, do not fork one more */
+                               msg_info_main ("%s process %P terminated normally",
+                                               g_quark_to_string (cur->type),
+                                               cur->pid);
+                       }
+                       else {
+                               if (WIFSIGNALED (res)) {
 #ifdef WCOREDUMP
-                               if (WCOREDUMP (res)) {
+                                       if (WCOREDUMP (res)) {
+                                               msg_warn_main (
+                                                               "%s process %P terminated abnormally by signal: %d"
+                                                               " and created core file",
+                                                               g_quark_to_string (cur->type),
+                                                               cur->pid,
+                                                               WTERMSIG (res));
+                                       }
+                                       else {
+                                               msg_warn_main (
+                                                               "%s process %P terminated abnormally by signal: %d"
+                                                               " but NOT created core file",
+                                                               g_quark_to_string (cur->type),
+                                                               cur->pid,
+                                                               WTERMSIG (res));
+                                       }
+#else
                                        msg_warn_main (
-                                                       "%s process %P terminated abnormally by signal: %d"
-                                                       " and created core file",
+                                                       "%s process %P terminated abnormally by signal: %d",
                                                        g_quark_to_string (cur->type),
                                                        cur->pid,
                                                        WTERMSIG (res));
+#endif
                                }
                                else {
-                                       msg_warn_main (
-                                                       "%s process %P terminated abnormally by signal: %d"
-                                                       " but NOT created core file",
+                                       msg_warn_main ("%s process %P terminated abnormally "
+                                                       "with exit code %d",
                                                        g_quark_to_string (cur->type),
                                                        cur->pid,
-                                                       WTERMSIG (res));
+                                                       WEXITSTATUS (res));
                                }
-#else
-                               msg_warn_main (
-                                               "%s process %P terminated abnormally by signal: %d",
-                                               g_quark_to_string (cur->type),
-                                               cur->pid,
-                                               WTERMSIG (res));
-#endif
-                       }
-                       else {
-                               msg_warn_main ("%s process %P terminated abnormally "
-                                               "with exit code %d",
-                                               g_quark_to_string (cur->type),
-                                               cur->pid,
-                                               WEXITSTATUS (res));
+                               /* Fork another worker in replace of dead one */
+                               rspamd_check_core_limits (rspamd_main);
+                               rspamd_fork_delayed (cur->cf, cur->index, rspamd_main);
                        }
-                       /* Fork another worker in replace of dead one */
-                       rspamd_check_core_limits (rspamd_main);
-                       rspamd_fork_delayed (cur->cf, cur->index, rspamd_main);
-               }
 
-               event_del (&cur->srv_ev);
-               /* We also need to clean descriptors left */
-               close (cur->control_pipe[0]);
-               close (cur->srv_pipe[0]);
-               g_free (cur);
-       }
-       else {
-               for (i = 0; i < other_workers->len; i++) {
-                       if (g_array_index (other_workers, pid_t, i) == wrk) {
-                               g_array_remove_index_fast (other_workers, i);
-                               msg_info_main ("related process %P terminated", wrk);
+                       event_del (&cur->srv_ev);
+                       /* We also need to clean descriptors left */
+                       close (cur->control_pipe[0]);
+                       close (cur->srv_pipe[0]);
+                       g_free (cur);
+               }
+               else {
+                       for (i = 0; i < other_workers->len; i++) {
+                               if (g_array_index (other_workers, pid_t, i) == wrk) {
+                                       g_array_remove_index_fast (other_workers, i);
+                                       msg_info_main ("related process %P terminated", wrk);
+                               }
                        }
                }
        }