mirror of https://github.com/mpv-player/mpv
stream: make mp_input_check_interrupt thread-safe
The interrupt callback will can be called from another thread if the cache is enabled, and the stream disconnects. Then stream_reconnect() will call this function from within the cache thread. mp_input_check_interrupt() is not thread-safe due to read_events() not being thread-safe. It will call input callbacks added with mp_input_add_fd() - these callbacks lead to code not protected by locks, such as reading X11 events. Solve this by adding a stupid hack, which checks whether the calling thread is the main playback thread (i.e. calling the input callbacks will be safe). We can remove this hack later, but it requires at least moving the VO to its own thread first.
This commit is contained in:
parent
e0cf983e53
commit
93de4c81b9
|
@ -119,6 +119,8 @@ struct cmd_queue {
|
|||
struct input_ctx {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t wakeup;
|
||||
pthread_t mainthread;
|
||||
bool mainthread_set;
|
||||
struct mp_log *log;
|
||||
struct mpv_global *global;
|
||||
|
||||
|
@ -1640,13 +1642,20 @@ static bool test_abort(struct input_ctx *ictx)
|
|||
return false;
|
||||
}
|
||||
|
||||
void mp_input_set_main_thread(struct input_ctx *ictx)
|
||||
{
|
||||
ictx->mainthread = pthread_self();
|
||||
ictx->mainthread_set = true;
|
||||
}
|
||||
|
||||
bool mp_input_check_interrupt(struct input_ctx *ictx)
|
||||
{
|
||||
input_lock(ictx);
|
||||
bool res = test_abort(ictx);
|
||||
if (!res) {
|
||||
if (!res && ictx->mainthread_set &&
|
||||
pthread_equal(ictx->mainthread, pthread_self()) == 0)
|
||||
{
|
||||
read_events(ictx, 0);
|
||||
res = test_abort(ictx);
|
||||
}
|
||||
input_unlock(ictx);
|
||||
return res;
|
||||
|
|
|
@ -219,6 +219,8 @@ bool mp_input_use_alt_gr(struct input_ctx *ictx);
|
|||
void mp_input_run_cmd(struct input_ctx *ictx, int def_flags, const char **cmd,
|
||||
const char *location);
|
||||
|
||||
void mp_input_set_main_thread(struct input_ctx *ictx);
|
||||
|
||||
extern int async_quit_request;
|
||||
|
||||
#endif /* MPLAYER_INPUT_H */
|
||||
|
|
|
@ -1488,6 +1488,7 @@ struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction,
|
|||
// Return if all done.
|
||||
void mp_play_files(struct MPContext *mpctx)
|
||||
{
|
||||
mp_input_set_main_thread(mpctx->input);
|
||||
mpctx->quit_player_rc = EXIT_NONE;
|
||||
for (;;) {
|
||||
idle_loop(mpctx);
|
||||
|
|
Loading…
Reference in New Issue