diff --git a/event.cpp b/event.cpp index 986198598..2be69493b 100644 --- a/event.cpp +++ b/event.cpp @@ -19,6 +19,7 @@ #include "wutil.h" #include "function.h" +#include "input_common.h" #include "proc.h" #include "parser.h" #include "common.h" @@ -441,6 +442,16 @@ static int event_is_killed(const event_t &e) return std::find(killme.begin(), killme.end(), &e) != killme.end(); } +/* Callback for firing (and then deleting) an event */ +static void fire_event_callback(void *arg) +{ + ASSERT_IS_MAIN_THREAD(); + assert(arg != NULL); + event_t *event = static_cast(arg); + event_fire(event); + delete event; +} + /** Perform the specified event. Since almost all event firings will not be matched by even a single event handler, we make sure to @@ -488,6 +499,14 @@ static void event_fire_internal(const event_t &event) if (fire.empty()) return; + if (signal_is_blocked()) + { + /* Fix for https://github.com/fish-shell/fish-shell/issues/608. Don't run event handlers while signals are blocked. */ + event_t *heap_event = new event_t(event); + input_common_add_callback(fire_event_callback, heap_event); + return; + } + /* Iterate over our list of matching events */ @@ -637,10 +656,10 @@ void event_fire_signal(int signal) } -void event_fire(event_t *event) +void event_fire(const event_t *event) { - if (event && (event->type == EVENT_SIGNAL)) + if (event && event->type == EVENT_SIGNAL) { event_fire_signal(event->param1.signal); } diff --git a/event.h b/event.h index 5f7c8080f..73db7351d 100644 --- a/event.h +++ b/event.h @@ -144,7 +144,7 @@ bool event_is_signal_observed(int signal); \param event the specific event whose handlers should fire. If null, then all delayed events will be fired. */ -void event_fire(event_t *event); +void event_fire(const event_t *event); /** Like event_fire, but takes a signal directly. */ void event_fire_signal(int signal); diff --git a/input.h b/input.h index da4eba8eb..484551444 100644 --- a/input.h +++ b/input.h @@ -128,7 +128,6 @@ bool input_terminfo_get_name(const wcstring &seq, wcstring &name); /** Return a list of all known terminfo names */ wcstring_list_t input_terminfo_get_names(bool skip_null); - /** Returns the input function code for the given input function name. */ wchar_t input_function_get_code(const wcstring &name); diff --git a/input_common.h b/input_common.h index 02b7359eb..1041e3fe5 100644 --- a/input_common.h +++ b/input_common.h @@ -56,6 +56,4 @@ void input_common_unreadch(wint_t ch); /** Adds a callback to be invoked at the next turn of the "event loop." The callback function will be invoked and passed arg. */ void input_common_add_callback(void (*callback)(void *), void *arg); - - #endif