aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-08-15 11:49:34 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-08-15 11:52:07 +0100
commite67ced158a0cac42f6b89a18552dbd69c8f67c54 (patch)
tree2f1bba002d8cba7255c1ddd264268b6de73e6a87
parentcc77b892b58494b3795d044b26d9c02e92ebc8f4 (diff)
downloadrspamd-e67ced158a0cac42f6b89a18552dbd69c8f67c54.tar.gz
rspamd-e67ced158a0cac42f6b89a18552dbd69c8f67c54.zip
[Fix] Try to deal with multiple workers terminated
-rw-r--r--src/rspamd.c109
1 files changed, 55 insertions, 54 deletions
diff --git a/src/rspamd.c b/src/rspamd.c
index 9bea4b5c0..5692e315b 100644
--- a/src/rspamd.c
+++ b/src/rspamd.c
@@ -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);
+ }
}
}
}