summaryrefslogtreecommitdiffstats
path: root/player/client.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-06 17:02:47 +0200
committerwm4 <wm4@nowhere>2014-09-06 17:02:47 +0200
commit017b3fa9dbbed1bcd5711599e42513daf5009fd0 (patch)
tree12fcf673bdb3d08038c6d5ad67150238f866d0e4 /player/client.c
parent348dfd93c4178633d3995a955045fafb7e9209d3 (diff)
downloadmpv-017b3fa9dbbed1bcd5711599e42513daf5009fd0.tar.bz2
mpv-017b3fa9dbbed1bcd5711599e42513daf5009fd0.tar.xz
lua: synchronously wait until scripts are loaded
This makes the player wait until each script is loaded. Do this to give the script a chance to setup all its event handlers. It might also be useful to allow a script to change options that matter for playback. While waiting for a script to be loaded, the player actually accepts input. This is needed because the scripts can execute player commands anyway while they are being "loaded". The player won't react to most commands though: it can't quit or navigate the playlist in this state. For deciding whether a script is finally loaded, we use a cheap hack: if mpv_wait_event() is called, it's considered loaded. Let's hope this is good enough. I think it's better than introducing explicit API for this. Although I'm sure this will turn out as too simplistic some time in the future, the same would probably happen with a more explicit API.
Diffstat (limited to 'player/client.c')
-rw-r--r--player/client.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/player/client.c b/player/client.c
index f1e824fc5d..41f7e12289 100644
--- a/player/client.c
+++ b/player/client.c
@@ -118,6 +118,7 @@ struct mpv_handle {
int properties_updating;
uint64_t property_event_masks; // or-ed together event masks of all properties
+ bool fuzzy_initialized;
struct mp_log_buffer *messages;
};
@@ -151,6 +152,22 @@ int mp_clients_num(struct MPContext *mpctx)
return num_clients;
}
+// Test for "fuzzy" initialization of all clients. That is, all clients have
+// at least called mpv_wait_event() at least once since creation (or exited).
+bool mp_clients_all_initialized(struct MPContext *mpctx)
+{
+ bool all_ok = true;
+ pthread_mutex_lock(&mpctx->clients->lock);
+ for (int n = 0; n < mpctx->clients->num_clients; n++) {
+ struct mpv_handle *ctx = mpctx->clients->clients[n];
+ pthread_mutex_lock(&ctx->lock);
+ all_ok &= ctx->fuzzy_initialized;
+ pthread_mutex_unlock(&ctx->lock);
+ }
+ pthread_mutex_unlock(&mpctx->clients->lock);
+ return all_ok;
+}
+
static void invalidate_global_event_mask(struct mpv_handle *ctx)
{
pthread_mutex_lock(&ctx->clients->lock);
@@ -377,6 +394,7 @@ mpv_handle *mpv_create(void)
mpv_handle *ctx = mp_new_client(mpctx->clients, "main");
if (ctx) {
ctx->owner = true;
+ ctx->fuzzy_initialized = true;
// Set some defaults.
mpv_set_option_string(ctx, "config", "no");
mpv_set_option_string(ctx, "idle", "yes");
@@ -599,6 +617,10 @@ mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout)
pthread_mutex_lock(&ctx->lock);
+ if (!ctx->fuzzy_initialized && ctx->clients->mpctx->input)
+ mp_input_wakeup(ctx->clients->mpctx->input);
+ ctx->fuzzy_initialized = true;
+
if (timeout < 0)
timeout = 1e20;
if (ctx->queued_wakeup)