mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-17 05:33:52 -04:00
timerfd: use non-blocking mode, fixes dead lock
Since we cancel the timers every now and then, there's a (small) chance that one handler cancels a timer that has triggered in the same epoll() iteration. When this happens, read() blocks. Fix by making the timer FDs non-blocking, and simply returning when we read 0 bytes.
This commit is contained in:
parent
035ace33b6
commit
b27cd9cedf
2 changed files with 25 additions and 5 deletions
23
terminal.c
23
terminal.c
|
|
@ -117,6 +117,11 @@ fdm_flash(struct fdm *fdm, int fd, int events, void *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Cancelled by other handler in *this* epoll() iteration */
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_DBG("flash timer expired %llu times",
|
||||
(unsigned long long)expiration_count);
|
||||
|
||||
|
|
@ -142,6 +147,11 @@ fdm_blink(struct fdm *fdm, int fd, int events, void *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Cancelled by other handler in *this* epoll() iteration */
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_DBG("blink timer expired %llu times",
|
||||
(unsigned long long)expiration_count);
|
||||
|
||||
|
|
@ -189,6 +199,11 @@ fdm_delayed_render(struct fdm *fdm, int fd, int events, void *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (ret1 == 0 && ret2 == 0) {
|
||||
/* Cancelled by other handler in *this* epoll() iteration */
|
||||
return true;
|
||||
}
|
||||
|
||||
render_refresh(term);
|
||||
|
||||
/* Reset timers */
|
||||
|
|
@ -304,16 +319,16 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
|||
LOG_ERRNO("failed to open PTY");
|
||||
goto close_fds;
|
||||
}
|
||||
if ((flash_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC)) == -1) {
|
||||
if ((flash_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK)) == -1) {
|
||||
LOG_ERRNO("failed to create flash timer FD");
|
||||
goto close_fds;
|
||||
}
|
||||
if ((blink_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC)) == -1) {
|
||||
if ((blink_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK)) == -1) {
|
||||
LOG_ERRNO("failed to create blink timer FD");
|
||||
goto close_fds;
|
||||
}
|
||||
if ((delay_lower_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC)) == -1 ||
|
||||
(delay_upper_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC)) == -1)
|
||||
if ((delay_lower_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK)) == -1 ||
|
||||
(delay_upper_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK)) == -1)
|
||||
{
|
||||
LOG_ERRNO("failed to create delayed rendering timer FDs");
|
||||
goto close_fds;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue