From ed1bdf9b1aa4effe408ad41ac81eaf9b079208ba Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Mon, 16 Jan 2023 15:55:56 +0530 Subject: [PATCH] gl: Fix crash in cocoa due to race in gst_gl_context_activate() We create a new context in `gst_gl_context_create_thread()` and then activate it on the current thread. Thereafter we assume that the current thread continues to be the active thread for that context and call `gst_gl_context_fill_info()` which asserts that the current thread is the active thread. However, if at the same time a different thread calls `send_message_async()`, it will call into `gst_gl_window_cocoa_send_message_async()` which will schedule the message to be invoked using GCD. That anonymous function will also call `gst_gl_context_activate()`, which creates a race, which can lead to: ``` gst_gl_context_fill_info: assertion 'context->priv->active_thread == g_thread_self ()' failed ``` Fix it by using `gst_gl_context_thread_add()` to invoke `fill_info()` on the context. Part-of: --- .../gst-libs/gst/gl/gstglcontext.c | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcontext.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcontext.c index 3056a4ab5a..4eac6b23d1 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcontext.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcontext.c @@ -1194,8 +1194,19 @@ _build_extension_string (GstGLContext * context) return ext_g_str; } -//gboolean -//gst_gl_context_create (GstGLContext * context, GstGLContext * other_context, GError ** error) +typedef struct +{ + GError **error; + gboolean ret; +} FillInfoCtx; + +static void +fill_info (GstGLContext * context, gpointer data) +{ + FillInfoCtx *ctx = data; + ctx->ret = gst_gl_context_fill_info (context, ctx->error); +} + static gpointer gst_gl_context_create_thread (GstGLContext * context) { @@ -1360,9 +1371,14 @@ gst_gl_context_create_thread (GstGLContext * context) g_free (display_api_s); GST_DEBUG_OBJECT (context, "Filling info"); - if (!gst_gl_context_fill_info (context, error)) { - g_assert (error == NULL || *error != NULL); - goto failure; + { + FillInfoCtx ctx = { 0 }; + ctx.error = error; + gst_gl_context_thread_add (context, fill_info, &ctx); + if (!ctx.ret) { + g_assert (error == NULL || *error != NULL); + goto failure; + } } context->priv->alive = TRUE;