summaryrefslogtreecommitdiffstats
path: root/player/client.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-09-21 15:55:34 +0200
committerwm4 <wm4@nowhere>2016-09-21 17:34:55 +0200
commit14c232bdbfbb16f427632d579430fa1a522f7f73 (patch)
tree3e5cf05ca68f71f79d9467c1ce482b2feeb56a29 /player/client.c
parent47f3cc7e6bf78609551312f84c93cccf194a5930 (diff)
downloadmpv-14c232bdbfbb16f427632d579430fa1a522f7f73.tar.bz2
mpv-14c232bdbfbb16f427632d579430fa1a522f7f73.tar.xz
client API: fix init/destruction race conditions
mp_new_client() blatantly accessed some mutex-protected state outside of the mutex. The destruction code is in theory OK, but with changes in the following commits it'll be a bit hard to guarantee that it stays this way. Add a simple flag that makes adding new clients impossible, so that having no clients after shutdown_clients() remains guaranteed.
Diffstat (limited to 'player/client.c')
-rw-r--r--player/client.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/player/client.c b/player/client.c
index 5d81f7c93b..93db0bb3d2 100644
--- a/player/client.c
+++ b/player/client.c
@@ -66,7 +66,8 @@ struct mp_client_api {
struct mpv_handle **clients;
int num_clients;
- uint64_t event_masks; // combined events of all clients, or 0 if unknown
+ uint64_t event_masks; // combined events of all clients, or 0 if unknown
+ bool shutting_down; // do not allow new clients
struct mp_custom_protocol *custom_protocols;
int num_custom_protocols;
@@ -206,8 +207,17 @@ bool mp_client_exists(struct MPContext *mpctx, const char *client_name)
return r;
}
+void mp_client_enter_shutdown(struct MPContext *mpctx)
+{
+ pthread_mutex_lock(&mpctx->clients->lock);
+ mpctx->clients->shutting_down = true;
+ pthread_mutex_unlock(&mpctx->clients->lock);
+}
+
struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name)
{
+ pthread_mutex_lock(&clients->lock);
+
char nname[MAX_CLIENT_NAME];
for (int n = 1; n < 1000; n++) {
if (!name)
@@ -222,10 +232,10 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name
nname[0] = '\0';
}
- if (!nname[0])
+ if (!nname[0] || clients->shutting_down) {
+ pthread_mutex_unlock(&clients->lock);
return NULL;
-
- pthread_mutex_lock(&clients->lock);
+ }
int num_events = 1000;