vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit ff67c4d571e0361ad10682aa7e5eb2b4c8a8ec8c
parent 7613425e3b8e110f382d530058c01bb8d89e4e99
Author: Florian Fischer <florian.fischer@muhq.space>
Date:   Wed, 25 Dec 2024 16:13:54 +0100

check the life time of subprocesses before freeing vis

Currently there is now way for long running subprocesses like language
servers to gracefully shutdown.
When reacting to the QUIT event and invalidating the process handle
the subprocess will never be killed and destroyed because the
subprocesses are only checked during vis_run.

Collecting and killing subprocesses with invalid handles after the
QUIT event allows graceful shutdown.

Diffstat:
Mvis-subprocess.c | 16++++++++++++++++
Mvis-subprocess.h | 1+
Mvis.c | 1+
3 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/vis-subprocess.c b/vis-subprocess.c @@ -230,3 +230,19 @@ void vis_process_tick(Vis *vis, fd_set *readfds) { } } } + +/** + * Checks if each subprocess from the pool is dead or needs to be + * killed then raises an event or kills it if necessary. + */ +void vis_process_waitall(Vis *vis) { + for (Process **pointer = &process_pool; *pointer; ) { + Process *current = *pointer; + if (!wait_or_kill_process(vis, current)) { + pointer = &current->next; + } else { + /* update our iteration pointer */ + *pointer = destroy_process(current); + } + } +} diff --git a/vis-subprocess.h b/vis-subprocess.h @@ -27,4 +27,5 @@ Process *vis_process_communicate(Vis *, const char *command, const char *name, Invalidator **invalidator); int vis_process_before_tick(fd_set *); void vis_process_tick(Vis *, fd_set *); +void vis_process_waitall(Vis *); #endif diff --git a/vis.c b/vis.c @@ -623,6 +623,7 @@ void vis_free(Vis *vis) { while (vis->windows) vis_window_close(vis->windows); vis_event_emit(vis, VIS_EVENT_QUIT); + vis_process_waitall(vis); file_free(vis, vis->command_file); file_free(vis, vis->search_file); file_free(vis, vis->error_file);