diff options
author | wm4 <wm4@nowhere> | 2019-10-24 19:12:36 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2019-10-24 19:12:36 +0200 |
commit | b0827b4dc4417de36e596c5adde9cd28605fdf81 (patch) | |
tree | f1afd175e8318a6a3d87cabe56acc0daa93e62ef /player/client.c | |
parent | 5d5fdb77e990f95e0a51e16c7349a19e8cebc272 (diff) | |
download | mpv-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.c | 10 |
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) { |