summaryrefslogtreecommitdiffstats
path: root/player/client.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-10-24 19:12:36 +0200
committerwm4 <wm4@nowhere>2019-10-24 19:12:36 +0200
commitb0827b4dc4417de36e596c5adde9cd28605fdf81 (patch)
treef1afd175e8318a6a3d87cabe56acc0daa93e62ef /player/client.c
parent5d5fdb77e990f95e0a51e16c7349a19e8cebc272 (diff)
downloadmpv-b0827b4dc4417de36e596c5adde9cd28605fdf81.tar.bz2
mpv-b0827b4dc4417de36e596c5adde9cd28605fdf81.tar.xz
client API: avoid lost wakeups
The commit linked below added temporary unlocking to update_prop(), which is indirectly called by mpv_wait_event(). If an unlock happens, and no property change event is returned, we must re-poll the event queue. Rechecking the state on unlocks is basically a standard requirement for code using condition variables. Untested beyond a simple test. Fixes: 065c307e8e7dbf
Diffstat (limited to 'player/client.c')
-rw-r--r--player/client.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/player/client.c b/player/client.c
index cbbdb77c90..8df4b26b99 100644
--- a/player/client.c
+++ b/player/client.c
@@ -139,7 +139,7 @@ struct mpv_handle {
};
static bool gen_log_message_event(struct mpv_handle *ctx);
-static bool gen_property_change_event(struct mpv_handle *ctx);
+static bool gen_property_change_event(struct mpv_handle *ctx, bool *unlocked);
static void notify_property_events(struct mpv_handle *ctx, uint64_t event_mask);
void mp_clients_init(struct MPContext *mpctx)
@@ -834,12 +834,15 @@ mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout)
talloc_steal(event, event->data);
break;
}
+ bool unlocked = false;
// If there's a changed property, generate change event (never queued).
- if (gen_property_change_event(ctx))
+ if (gen_property_change_event(ctx, &unlocked))
break;
// Pop item from message queue, and return as event.
if (gen_log_message_event(ctx))
break;
+ if (unlocked)
+ continue;
int r = wait_wakeup(ctx, deadline);
if (r == ETIMEDOUT)
break;
@@ -1549,7 +1552,7 @@ static bool update_prop(struct mpv_handle *ctx, struct observe_property *prop)
// Set ctx->cur_event to a generated property change event, if there is any
// outstanding property.
-static bool gen_property_change_event(struct mpv_handle *ctx)
+static bool gen_property_change_event(struct mpv_handle *ctx, bool *unlocked)
{
if (!ctx->mpctx->initialized)
return false;
@@ -1570,6 +1573,7 @@ static bool gen_property_change_event(struct mpv_handle *ctx)
if (prop->changed && !prop->dead) {
prop->changed = false;
updated = update_prop(ctx, prop);
+ *unlocked = true; // not always; but good enough
}
if (prop->dead) {