summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwnoun <wnoun@outlook.com>2019-05-26 16:58:25 +0800
committerwm4 <wm4@nowhere>2019-09-20 13:54:17 +0200
commit35da5a4d8e9f8616eaa55af3219cbb6139d6d68c (patch)
tree7f8ba179101bedea7d545448fa3442bfa26871e4 /video
parentdb09d77e46128a68f06dc89d34bdc6045ace63f2 (diff)
downloadmpv-35da5a4d8e9f8616eaa55af3219cbb6139d6d68c.tar.bz2
mpv-35da5a4d8e9f8616eaa55af3219cbb6139d6d68c.tar.xz
render api: fix use-after-free
render api needs to wait for vo to be destroyed before frees the context. The purpose of kill_cb is to wake up render api after vo is destroyed, but uninit did that before kill_cb, so kill_cb tries using the freed memory. Remove kill_cb to fix the issue as uninit is able to do the work.
Diffstat (limited to 'video')
-rw-r--r--video/out/vo_libmpv.c14
1 files changed, 2 insertions, 12 deletions
diff --git a/video/out/vo_libmpv.c b/video/out/vo_libmpv.c
index 1c2a8acba0..3caa457e17 100644
--- a/video/out/vo_libmpv.c
+++ b/video/out/vo_libmpv.c
@@ -245,16 +245,6 @@ void mp_render_context_set_control_callback(mpv_render_context *ctx,
pthread_mutex_unlock(&ctx->control_lock);
}
-static void kill_cb(void *ptr)
-{
- struct mpv_render_context *ctx = ptr;
-
- pthread_mutex_lock(&ctx->update_lock);
- ctx->had_kill_update = true;
- pthread_cond_broadcast(&ctx->update_cond);
- pthread_mutex_unlock(&ctx->update_lock);
-}
-
void mpv_render_context_free(mpv_render_context *ctx)
{
if (!ctx)
@@ -269,7 +259,7 @@ void mpv_render_context_free(mpv_render_context *ctx)
// context. The above removal guarantees it can't come back (so ctx->vo
// can't change to non-NULL).
if (atomic_load(&ctx->in_use)) {
- kill_video_async(ctx->client_api, kill_cb, ctx);
+ kill_video_async(ctx->client_api);
while (atomic_load(&ctx->in_use)) {
// As long as the video decoders are not destroyed, they can still
@@ -279,7 +269,7 @@ void mpv_render_context_free(mpv_render_context *ctx)
if (ctx->dispatch)
mp_dispatch_queue_process(ctx->dispatch, 0);
- // Wait for kill_cb() or update() calls.
+ // Wait for update() calls.
pthread_mutex_lock(&ctx->update_lock);
if (!ctx->had_kill_update)
pthread_cond_wait(&ctx->update_cond, &ctx->update_lock);