ref counting issue fix for Context in gst-libs/gst/gl/gstglcontext.c
Matthew Waters
ystreet00 at gmail.com
Thu Feb 23 11:29:51 UTC 2017
So essentially this takes and keeps an extra ref while the context is
active on that thread. That makes sense.
Can you provide a git format-patch against master and attach it to a new
bug in bugzilla
https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer&component=gst-plugins-bad,
we can attribute your work and review the change properly :)
Cheers
-Matt
On 23/02/17 17:42, Frank VanZile wrote:
> There is a ref counting issue in gst-libs/gst/gl/gstglcontext.c.
> _GstGLContextPrivate holds onto GThread's without proper ref
> counting. when a thread was released I would get exceptions.
> see my previous email "heap corruption in gstreamer when IP camera
> with an rtp stream disconnects (losses network)"
>
>
>
> --- a/gst-libs/gst/gl/gstglcontext.c
> +++ b/gst-libs/gst/gl/gstglcontext.c
> @@ -371,7 +371,7 @@ gst_gl_context_new (GstGLDisplay * display)
> * @context_type: a #GstGLPlatform specifying the type of context in
> @handle
> * @available_apis: a #GstGLAPI containing the available OpenGL apis
> in @handle
> *
> - * Wraps an existing OpenGL context into a #GstGLContext.
> + * Wraps an existing OpenGL context into a #GstGLContext.
> *
> * Note: The caller is responsible for ensuring that the OpenGL context
> * represented by @handle stays alive while the returned
> #GstGLContext is
> @@ -668,19 +668,37 @@ gst_gl_context_finalize (GObject * object)
> g_cond_wait (&context->priv->destroy_cond,
> &context->priv->render_lock);
> GST_INFO_OBJECT (context, "gl thread joined");
>
> - g_thread_unref (context->priv->gl_thread);
> - context->priv->gl_thread = NULL;
> + if (context->priv->gl_thread) {
> + g_thread_unref (context->priv->gl_thread);
> + context->priv->gl_thread = NULL;
> + }
> }
> g_mutex_unlock (&context->priv->render_lock);
>
> gst_gl_window_set_close_callback (context->window, NULL, NULL,
> NULL);
> gst_object_unref (context->window);
> + context->window = NULL;
> }
>
> - if (context->priv->sharegroup)
> + if (context->priv->active_thread) {
> + g_thread_unref (context->priv->active_thread);
> + context->priv->active_thread = NULL;
> + }
> +
> + if (context->priv->gl_thread) {
> + g_thread_unref (context->priv->gl_thread);
> + context->priv->gl_thread = NULL;
> + }
> +
> + if (context->priv->sharegroup) {
> _context_share_group_unref (context->priv->sharegroup);
> + context->priv->sharegroup = NULL;
> + }
>
> - gst_object_unref (context->display);
> + if (context->display) {
> + gst_object_unref (context->display);
> + context->display = NULL;
> + }
>
> if (context->gl_vtable) {
> g_slice_free (GstGLFuncs, context->gl_vtable);
> @@ -729,10 +747,19 @@ gst_gl_context_activate (GstGLContext * context,
> gboolean activate)
> result = context_class->activate (context, activate);
>
> if (result && activate) {
> - context->priv->active_thread = g_thread_self ();
> + GThread *saveOldThread = context->priv->active_thread; //save the
> old thread
> + context->priv->active_thread = g_thread_self (); // ref count is
> 1, does not increment count
> + g_thread_ref (context->priv->active_thread); //add ref count
> + if (saveOldThread) {
> + g_thread_unref (saveOldThread); // release old thread
> + }
> +
> g_private_set (¤t_context_key, context);
> } else {
> - context->priv->active_thread = NULL;
> + if (context->priv->active_thread) {
> + g_thread_unref (context->priv->active_thread);
> + context->priv->active_thread = NULL;
> + }
> g_private_set (¤t_context_key, NULL);
> }
> GST_OBJECT_UNLOCK (context);
> @@ -1002,7 +1029,7 @@ gst_gl_context_create (GstGLContext * context,
> _context_share_group_ref (other_context->priv->sharegroup);
>
> context->priv->gl_thread = g_thread_new ("gstglcontext",
> - (GThreadFunc) gst_gl_context_create_thread, context);
> + (GThreadFunc) gst_gl_context_create_thread, context); // ref
> count 2
>
> while (!context->priv->created)
> g_cond_wait (&context->priv->create_cond,
> &context->priv->render_lock);
> @@ -1728,10 +1755,19 @@ gst_gl_wrapped_context_get_gl_platform
> (GstGLContext * context)
> static gboolean
> gst_gl_wrapped_context_activate (GstGLContext * context, gboolean
> activate)
> {
> - if (activate)
> - context->priv->gl_thread = g_thread_self ();
> - else
> - context->priv->gl_thread = NULL;
> + if (activate) {
> + GThread *saveOldThread = context->priv->gl_thread; // save old
> thread
> + context->priv->gl_thread = g_thread_self (); // ref count is one
> + g_thread_ref (context->priv->gl_thread); // add ref count
> + if (saveOldThread) {
> + g_thread_unref (saveOldThread); // release old thread
> + }
> + } else {
> + if (context->priv->gl_thread) {
> + g_thread_unref (context->priv->gl_thread);
> + context->priv->gl_thread = NULL;
> + }
> + }
>
> return TRUE;
> }
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 516 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20170223/00f66e6c/attachment.sig>
More information about the gstreamer-devel
mailing list