summaryrefslogtreecommitdiffstats
path: root/osdep/terminal-unix.c
diff options
context:
space:
mode:
authorNRK <nrk@disroot.org>2023-10-08 02:06:25 +0600
committersfan5 <sfan5@live.de>2023-10-13 11:36:01 +0200
commit1abe908e31c40231e52ab2bc9d13ac66558dea73 (patch)
tree1951396dfc9f7385157140186bd27a8f4ba0a5b9 /osdep/terminal-unix.c
parente41add29d46bdfc8fdb9933453315e6784717f53 (diff)
downloadmpv-1abe908e31c40231e52ab2bc9d13ac66558dea73.tar.bz2
mpv-1abe908e31c40231e52ab2bc9d13ac66558dea73.tar.xz
terminal-unix: avoid data-race on do_deactivate_getch2
do_deactivate_getch2() touches some global variables which *might have* been fine if the terminal thread was the one that received the signal but AFAIK which thread will handle the signal is not well defined. in my case, when quitting mpv with CTRL+C the main thread receives the signal rather than the terminal thread and touches those globals without synchronization. caught by ThreadSanitizer. the solution is to move the do_deactivate_getch2() call outside of the signal handler.
Diffstat (limited to 'osdep/terminal-unix.c')
-rw-r--r--osdep/terminal-unix.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/osdep/terminal-unix.c b/osdep/terminal-unix.c
index b20a251270..0ad3729eda 100644
--- a/osdep/terminal-unix.c
+++ b/osdep/terminal-unix.c
@@ -405,7 +405,6 @@ static void close_tty(void)
static void quit_request_sighandler(int signum)
{
int saved_errno = errno;
- do_deactivate_getch2();
(void)write(death_pipe[1], &(char){1}, 1);
errno = saved_errno;
}
@@ -432,8 +431,10 @@ static void *terminal_thread(void *ptr)
*/
bool is_fg = tcgetpgrp(tty_in) == getpgrp();
int r = polldev(fds, stdin_ok && is_fg ? 2 : 1, buf.len ? ESC_TIMEOUT : INPUT_TIMEOUT);
- if (fds[0].revents)
+ if (fds[0].revents) {
+ do_deactivate_getch2();
break;
+ }
if (fds[1].revents) {
int retval = read(tty_in, &buf.b[buf.len], BUF_LEN - buf.len);
if (!retval || (retval == -1 && errno != EINTR && errno != EAGAIN && errno != EIO))