1
0
mirror of https://github.com/mpv-player/mpv synced 2025-03-20 02:09:52 +00:00

client API: fix race condition on client exit

The relatively recently added property update code has a race condition
when clients exit. It still tried to access mpv_handle during and after
it was destroyed.

The reason is that it unlocks the lock for the mpv_handle list (while
mpv_handle is locked), but nothing in mp_destroy_client() cares about
this case. The latter function locks mpv_handle only before/while it
makes sure all of its activity is coming to an end, such as asynchronous
requests, and property updates that are in progress. It did not include
the case when mp_client_send_property_changes() was still calling
send_client_property_changes() with mpv_handle locked.

Fix this by checking the mpv_handle.destroying field. This field can be
set only when mpv_handle is locked. While we're checking the lock, the
mpv_handle list is still locked, so at worst we might be at the point
before mp_destroy_client() locks the list again and finally destroys the
mpv_handle.

This is a hard to reproduce race condition which I spotted only once in
valgrind by chance, so the fix is unconfirmed.
This commit is contained in:
wm4 2020-02-23 17:52:21 +01:00
parent bc3678da65
commit 4839106a99

View File

@ -1662,7 +1662,7 @@ void mp_client_send_property_changes(struct MPContext *mpctx)
struct mpv_handle *ctx = clients->clients[n];
pthread_mutex_lock(&ctx->lock);
if (!ctx->has_pending_properties) {
if (!ctx->has_pending_properties || ctx->destroying) {
pthread_mutex_unlock(&ctx->lock);
continue;
}