mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-14 08:21:27 -04:00
term_shutdown(): cleanup
* Close FDs, then delay destruction to next epoll() call * Destroy window before destroying terminal
This commit is contained in:
parent
c824aa2ef5
commit
70b236d66d
1 changed files with 35 additions and 49 deletions
84
terminal.c
84
terminal.c
|
|
@ -468,77 +468,53 @@ close_fds:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
close_fd(struct terminal *term, int *fd)
|
|
||||||
{
|
|
||||||
if (*fd == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fdm_del(term->fdm, *fd);
|
|
||||||
close(*fd);
|
|
||||||
*fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
close_fds(struct terminal *term)
|
|
||||||
{
|
|
||||||
close_fd(term, &term->delayed_render_timer.lower_fd);
|
|
||||||
close_fd(term, &term->delayed_render_timer.upper_fd);
|
|
||||||
close_fd(term, &term->blink.fd);
|
|
||||||
close_fd(term, &term->flash.fd);
|
|
||||||
close_fd(term, &term->ptmx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
fdm_shutdown(struct fdm *fdm, int fd, int events, void *data)
|
fdm_shutdown(struct fdm *fdm, int fd, int events, void *data)
|
||||||
{
|
{
|
||||||
LOG_DBG("FDM shutdown");
|
LOG_DBG("FDM shutdown");
|
||||||
struct terminal *term = data;
|
struct terminal *term = data;
|
||||||
struct wayland *wayl = term->wl;
|
|
||||||
|
|
||||||
|
/* Kill the event FD */
|
||||||
fdm_del(term->fdm, fd);
|
fdm_del(term->fdm, fd);
|
||||||
close(fd);
|
|
||||||
|
|
||||||
/*
|
wayl_win_destroy(term->window);
|
||||||
* Now there shouldn't be any more callbacks or events that can
|
term->window = NULL;
|
||||||
* trigger, meaning it should be safe to destroy the terminal.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
struct wayland *wayl __attribute__((unused)) = term->wl;
|
||||||
assert(wayl->focused != term);
|
assert(wayl->focused != term);
|
||||||
assert(wayl->moused != term);
|
assert(wayl->moused != term);
|
||||||
|
|
||||||
tll_foreach(wayl->terms, it) {
|
|
||||||
if (it->item == term) {
|
|
||||||
tll_remove(wayl->terms, it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wayl->last_exit_value = term_destroy(term);
|
int exit_code = term_destroy(term);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
term_shutdown(struct terminal *term)
|
term_shutdown(struct terminal *term)
|
||||||
{
|
{
|
||||||
/* Ensure we don't get any more events */
|
if (term->is_shutting_down)
|
||||||
close_fds(term);
|
return true;
|
||||||
|
|
||||||
/* Destroy the wayland window, and consume the trail of Wayland events */
|
term->is_shutting_down = true;
|
||||||
wayl_win_destroy(term->window);
|
|
||||||
wl_display_roundtrip(term->wl->display);
|
|
||||||
term->window = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we no longer receive any more events referring to us, and it _should_ be safe to destroy ourselves now.
|
* Close FDs then postpone self-destruction to the next poll
|
||||||
*
|
* iteration, by creating an event FD that we trigger immediately.
|
||||||
* However, in the (unlikely) event that there are events already
|
|
||||||
* queued up by the FDM, we delay the self-destruction to the next
|
|
||||||
* FDM poll iteration.
|
|
||||||
*
|
|
||||||
* This is done by opening an event FD and adding it to the FDM.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
fdm_del(term->fdm, term->delayed_render_timer.lower_fd);
|
||||||
|
fdm_del(term->fdm, term->delayed_render_timer.upper_fd);
|
||||||
|
fdm_del(term->fdm, term->blink.fd);
|
||||||
|
fdm_del(term->fdm, term->flash.fd);
|
||||||
|
fdm_del(term->fdm, term->ptmx);
|
||||||
|
|
||||||
|
term->delayed_render_timer.lower_fd = -1;
|
||||||
|
term->delayed_render_timer.upper_fd = -1;
|
||||||
|
term->blink.fd = -1;
|
||||||
|
term->flash.fd = -1;
|
||||||
|
term->ptmx = -1;
|
||||||
|
|
||||||
int event_fd = eventfd(0, EFD_CLOEXEC);
|
int event_fd = eventfd(0, EFD_CLOEXEC);
|
||||||
if (event_fd == -1) {
|
if (event_fd == -1) {
|
||||||
LOG_ERRNO("failed to create terminal shutdown event FD");
|
LOG_ERRNO("failed to create terminal shutdown event FD");
|
||||||
|
|
@ -554,7 +530,6 @@ term_shutdown(struct terminal *term)
|
||||||
if (write(event_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) {
|
if (write(event_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) {
|
||||||
LOG_ERRNO("failed to send terminal shutdown event");
|
LOG_ERRNO("failed to send terminal shutdown event");
|
||||||
fdm_del(term->fdm, event_fd);
|
fdm_del(term->fdm, event_fd);
|
||||||
close(event_fd);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,7 +542,18 @@ term_destroy(struct terminal *term)
|
||||||
if (term == NULL)
|
if (term == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
close_fds(term);
|
tll_foreach(term->wl->terms, it) {
|
||||||
|
if (it->item == term) {
|
||||||
|
tll_remove(term->wl->terms, it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fdm_del(term->fdm, term->delayed_render_timer.lower_fd);
|
||||||
|
fdm_del(term->fdm, term->delayed_render_timer.upper_fd);
|
||||||
|
fdm_del(term->fdm, term->blink.fd);
|
||||||
|
fdm_del(term->fdm, term->flash.fd);
|
||||||
|
fdm_del(term->fdm, term->ptmx);
|
||||||
|
|
||||||
if (term->window != NULL)
|
if (term->window != NULL)
|
||||||
wayl_win_destroy(term->window);
|
wayl_win_destroy(term->window);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue