diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2016-11-13 16:07:24 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2016-11-13 16:07:24 +0100 |
commit | 018b9693812eb58e6d15602366c61e937a9ea930 (patch) | |
tree | 9511933abc8df58c81c50b3a23996775e2529ecc /src/gui | |
parent | 01f84430738b2a3e3987addc1a80197fcd078ba1 (diff) | |
download | weechat-018b9693812eb58e6d15602366c61e937a9ea930.zip |
core: fix deadlock when quitting after a signal is received (closes #32)
The code in signal handers (SIGHUP, SIGQUIT, SIGTERM) is moved into main
loop, this hopefully fixes the deadlock when quitting after receiving
one of these signals.
The code in SIGWINCH signal handler is moved too (even if it shouldn't
be a problem).
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/curses/gui-curses-key.c | 9 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-main.c | 53 |
2 files changed, 57 insertions, 5 deletions
diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c index cd267064a..6529510f3 100644 --- a/src/gui/curses/gui-curses-key.c +++ b/src/gui/curses/gui-curses-key.c @@ -525,9 +525,12 @@ gui_key_read_cb (const void *pointer, void *data, int fd) if (ret == 0) { /* no data on stdin, terminal lost */ - log_printf (_("Terminal lost, exiting WeeChat...")); - (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL); - weechat_quit = 1; + if (!weechat_quit) + { + log_printf (_("Terminal lost, exiting WeeChat...")); + (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL); + weechat_quit = 1; + } return WEECHAT_RC_OK; } if (ret < 0) diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c index 8407f8c63..bcc32c38a 100644 --- a/src/gui/curses/gui-curses-main.c +++ b/src/gui/curses/gui-curses-main.c @@ -60,7 +60,8 @@ #include "gui-curses.h" -int gui_signal_sigwinch_received = 0; /* sigwinch signal (term resized) */ +volatile sig_atomic_t gui_signal_sigwinch_received = 0; /* sigwinch signal */ + /* (terminal has been resized) */ int gui_term_cols = 0; /* number of columns in terminal */ int gui_term_lines = 0; /* number of lines in terminal */ @@ -249,8 +250,51 @@ void gui_main_signal_sigwinch () { gui_signal_sigwinch_received = 1; +} + +/* + * Callback for signals received that will make WeeChat quit. + */ + +void +gui_main_handle_quit_signals () +{ + char str_signal[64], str_weechat_signal[64]; + int rc; + + switch (weechat_quit_signal) + { + case SIGHUP: + snprintf (str_signal, sizeof(str_signal), "SIGHUP"); + break; + case SIGQUIT: + snprintf (str_signal, sizeof(str_signal), "SIGQUIT"); + break; + case SIGTERM: + snprintf (str_signal, sizeof(str_signal), "SIGTERM"); + break; + default: + str_signal[0] = '\0'; + break; + } + + if (str_signal[0]) + { + snprintf (str_weechat_signal, sizeof(str_weechat_signal), + "signal_%s", str_signal); + string_tolower(str_weechat_signal); + rc = hook_signal_send (str_weechat_signal, + WEECHAT_HOOK_SIGNAL_STRING, NULL); + if ((rc != WEECHAT_RC_OK_EAT) && !weechat_quit) + { + log_printf (_("Signal %s received, exiting WeeChat..."), + str_signal); + (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL); + weechat_quit = 1; + } + } - gui_window_ask_refresh (2); + weechat_quit_signal = 0; } /* @@ -416,6 +460,7 @@ gui_main_loop () (void) hook_signal_send ("signal_sigwinch", WEECHAT_HOOK_SIGNAL_STRING, NULL); gui_signal_sigwinch_received = 0; + gui_window_ask_refresh (2); } gui_color_pairs_auto_reset_pending = 0; @@ -425,6 +470,10 @@ gui_main_loop () /* run process (with fork) */ hook_process_exec (); + + /* handle signals received */ + if (weechat_quit_signal > 0) + gui_main_handle_quit_signals (); } /* remove keyboard hook */ |