diff --git a/src/igc.c b/src/igc.c index f63b0fe8c88..eb845ff7ae0 100644 --- a/src/igc.c +++ b/src/igc.c @@ -60,6 +60,7 @@ along with GNU Emacs. If not, see . */ #include "thread.h" #include "treesit.h" #include "termchar.h" +#include "keyboard.h" #ifdef HAVE_WINDOW_SYSTEM #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ @@ -1725,6 +1726,32 @@ scan_tty_list (mps_ss_t ss, void *start, void *end, void *closure) return MPS_RES_OK; } +static mps_res_t +scan_kbd_buffer_ambig (mps_ss_t ss, void *start, void *end, void *closure) +{ + igc_assert (start == kbd_buffer); + igc_assert (end == kbd_buffer + ARRAYELTS (kbd_buffer)); + + /* Instead of tracing the entire kbd_buffer, only scan the region from + kbd_fetch_ptr - 1 to kbd_store_ptr + 1. The -1/+1 is supposed to + cover the cases where MPS stops the mutator while those pointers + are being updated. */ + + union buffered_input_event *fetch = prev_kbd_event (kbd_fetch_ptr); + union buffered_input_event *store = next_kbd_event (kbd_store_ptr); + + if (fetch <= store - 2) + return scan_ambig (ss, fetch, store, closure); + else + { + mps_res_t res + = scan_ambig (ss, fetch, kbd_buffer + KBD_BUFFER_SIZE, closure); + if (res == MPS_RES_OK) + res = scan_ambig (ss, kbd_buffer, store, closure); + return res; + } +} + /*********************************************************************** Default pad, fwd, ... ***********************************************************************/ @@ -2905,6 +2932,14 @@ root_create_tty_list (struct igc *gc) scan_tty_list, "tty-list"); } +static void +root_create_kbd_buffer (struct igc *gc) +{ + root_create (gc, kbd_buffer, kbd_buffer + ARRAYELTS (kbd_buffer), + mps_rank_ambig (), scan_kbd_buffer_ambig, NULL, + true, "kbd-buffer"); +} + static void root_create_main_thread (struct igc *gc) { @@ -4934,6 +4969,7 @@ make_igc (void) root_create_main_thread (gc); root_create_exact_ptr (gc, ¤t_thread); root_create_exact_ptr (gc, &all_threads); + root_create_kbd_buffer (gc); enable_messages (gc, true); return gc; diff --git a/src/keyboard.c b/src/keyboard.c index 72c6e4c17d8..dac179e696c 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -423,12 +423,18 @@ static void do_async_work (void); /* Advance or retreat a buffered input event pointer. */ -static union buffered_input_event * +union buffered_input_event * next_kbd_event (union buffered_input_event *ptr) { return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1; } +union buffered_input_event * +prev_kbd_event (union buffered_input_event *ptr) +{ + return ptr == kbd_buffer ? kbd_buffer + KBD_BUFFER_SIZE - 1 : ptr - 1; +} + /* Like EVENT_START, but assume EVENT is an event. This pacifies gcc -Wnull-dereference, which might otherwise complain about earlier checks that EVENT is indeed an event. */ @@ -12892,10 +12898,6 @@ delete_kboard (KBOARD *kb) void init_keyboard (void) { -#ifdef HAVE_MPS - igc_root_create_ambig (kbd_buffer, kbd_buffer + ARRAYELTS (kbd_buffer), - "kbd-buffer"); -#endif /* This is correct before outermost invocation of the editor loop. */ command_loop_level = -1; quit_char = Ctl ('g'); diff --git a/src/keyboard.h b/src/keyboard.h index 38aa5a13b18..354cd13348e 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -533,6 +533,9 @@ extern char *dev_tty; /* Initial value for dev_tty. */ extern char const DEV_TTY[]; +union buffered_input_event *next_kbd_event (union buffered_input_event *); +union buffered_input_event *prev_kbd_event (union buffered_input_event *); + INLINE_HEADER_END enum async_work_type