After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 755554 - gtk: Wait at most 5s for calling something on the main thread
gtk: Wait at most 5s for calling something on the main thread
Status: RESOLVED INCOMPLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
unspecified
Other All
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-09-24 17:27 UTC by Sebastian Dröge (slomo)
Modified: 2018-05-06 15:21 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gtk: Wait at most 5s for calling something on the main thread (7.01 KB, patch)
2015-09-24 17:27 UTC, Sebastian Dröge (slomo)
none Details | Review
gtk: Wait at most 5s for calling something on the main thread (7.01 KB, patch)
2015-09-25 08:10 UTC, Sebastian Dröge (slomo)
none Details | Review
gtk: Wait at most 5s for calling something on the main thread (7.01 KB, patch)
2015-09-25 08:22 UTC, Sebastian Dröge (slomo)
none Details | Review

Description Sebastian Dröge (slomo) 2015-09-24 17:27:53 UTC
see commit message
Comment 1 Sebastian Dröge (slomo) 2015-09-24 17:27:59 UTC
Created attachment 312076 [details] [review]
gtk: Wait at most 5s for calling something on the main thread

In certain situations we might deadlock, main thread waiting for the
streaming thread, streaming thread waiting for the main thread.

With this we cut the deadlock and error out properly.
Comment 2 Nicolas Dufresne (ndufresne) 2015-09-24 17:37:16 UTC
Review of attachment 312076 [details] [review]:

::: ext/gtk/gstgtkbasesink.c
@@ +327,3 @@
+  gboolean timeout, ret;
+
+  ret = ! !gst_gtk_invoke_on_main ((GThreadFunc)

Was there before, but why would you want to use ! ! obscureness here, while you can write readable code ?

::: ext/gtk/gstgtkutils.c
@@ +29,3 @@
   GCond cond;
   gboolean fired;
+  gboolean timed_out;

Consistency, timeout in basesink vs timed_out here.

@@ +52,3 @@
+    g_mutex_clear (&info->lock);
+    g_cond_clear (&info->cond);
+    g_free (info);

Using g_main_context_invoke_full() with a destroy notify would avoid the duplication.

@@ +71,1 @@
+  info = g_new0 (struct invoke_context, 1);

Slice new please. I'd suggest having a new/free which will be clean with the invoke_full(),

@@ +80,1 @@
+  g_main_context_invoke (main_context, (GSourceFunc) gst_gtk_invoke_func, info);

Here.

@@ +91,3 @@
+      g_warning ("gtksink: Timed out to call something from the main thread");
+    *timeout = timed_out;
+    /* Leak everything on timeout */

The destroy notify will avoid the leak in a safe way.
Comment 3 Sebastian Dröge (slomo) 2015-09-24 17:41:23 UTC
(In reply to Nicolas Dufresne (stormer) from comment #2)
> Review of attachment 312076 [details] [review] [review]:
> 
> ::: ext/gtk/gstgtkbasesink.c
> @@ +327,3 @@
> +  gboolean timeout, ret;
> +
> +  ret = ! !gst_gtk_invoke_on_main ((GThreadFunc)
> 
> Was there before, but why would you want to use ! ! obscureness here, while
> you can write readable code ?

Boolean normalization.

> ::: ext/gtk/gstgtkutils.c
> @@ +29,3 @@
>    GCond cond;
>    gboolean fired;
> +  gboolean timed_out;
> 
> Consistency, timeout in basesink vs timed_out here.

Why does basesink matter here? :) And timeout is already the variable we use as out parameter.

> @@ +52,3 @@
> +    g_mutex_clear (&info->lock);
> +    g_cond_clear (&info->cond);
> +    g_free (info);
> 
> Using g_main_context_invoke_full() with a destroy notify would avoid the
> duplication.

No, because otherwise the struct is already freed after g_main_context_invoke() while we still want to get the result from it.

> @@ +71,1 @@
> +  info = g_new0 (struct invoke_context, 1);
> 
> Slice new please. I'd suggest having a new/free which will be clean with the
> invoke_full(),

No, GSlice is deprecated in newer GLib :)
Comment 4 Nicolas Dufresne (ndufresne) 2015-09-24 17:43:59 UTC
Deprecated ?
Comment 5 Nicolas Dufresne (ndufresne) 2015-09-24 19:21:52 UTC
(In reply to Sebastian Dröge (slomo) from comment #3)
> > @@ +52,3 @@
> > +    g_mutex_clear (&info->lock);
> > +    g_cond_clear (&info->cond);
> > +    g_free (info);
> > 
> > Using g_main_context_invoke_full() with a destroy notify would avoid the
> > duplication.
> 
> No, because otherwise the struct is already freed after
> g_main_context_invoke() while we still want to get the result from it.
> 

That is not correct. If you use a GDestroyNotify to free the structure (and correctly remove the two duplicate free blocks), the data will be destroy when gst_gtk_invoke_func () returns or if the main loop get destroyed without running the callback. You can also safely call g_source_remove() after a timeout to cleanup the callback if not run yet.
Comment 6 Nicolas Dufresne (ndufresne) 2015-09-24 19:23:46 UTC
Ah wait, nevermind, I just realise what you didn't say, the mutex and condition need to stay alive. In any case, make a free function, that will be cleaner (and that's what I care here, it's all very messy right now).
Comment 7 Nicolas Dufresne (ndufresne) 2015-09-24 19:29:46 UTC
And for the boolean, gst_gtk_base_sink == basesink in that context, you define boolean for when we have timed out, one is named timeout and the other timed_out, you could be more consistent.
Comment 8 Sebastian Dröge (slomo) 2015-09-25 08:07:30 UTC
(In reply to Nicolas Dufresne (stormer) from comment #7)
> And for the boolean, gst_gtk_base_sink == basesink in that context, you
> define boolean for when we have timed out, one is named timeout and the
> other timed_out, you could be more consistent.

I have no idea what you mean with this, but I'll just call them all timeout now :)
Comment 9 Sebastian Dröge (slomo) 2015-09-25 08:10:46 UTC
Created attachment 312114 [details] [review]
gtk: Wait at most 5s for calling something on the main thread

In certain situations we might deadlock, main thread waiting for the
streaming thread, streaming thread waiting for the main thread.

With this we cut the deadlock and error out properly.
Comment 10 Thibault Saunier 2015-09-25 08:17:37 UTC
Review of attachment 312114 [details] [review]:

LGTM
Comment 11 Matthew Waters (ystreet00) 2015-09-25 08:19:44 UTC
Review of attachment 312114 [details] [review]:

There exists possible memory corruption here.

::: ext/gtk/gstgtkutils.c
@@ +99,3 @@
+    /* Leak everything on timeout */
+  } else {
+    free_invoke_context (info);

Won't this double free if timeout_return == NULL and a timeout occurs?
Comment 12 Sebastian Dröge (slomo) 2015-09-25 08:21:20 UTC
Yes, because of the renaming of the timeout variables I broke it now. Thanks! I won't merge this for 1.6.0 btw, that's 1.6.1 material
Comment 13 Sebastian Dröge (slomo) 2015-09-25 08:22:36 UTC
Created attachment 312116 [details] [review]
gtk: Wait at most 5s for calling something on the main thread

In certain situations we might deadlock, main thread waiting for the
streaming thread, streaming thread waiting for the main thread.

With this we cut the deadlock and error out properly.
Comment 14 Nicolas Dufresne (ndufresne) 2015-09-25 17:10:58 UTC
(In reply to Sebastian Dröge (slomo) from comment #12)
> Yes, because of the renaming of the timeout variables I broke it now.
> Thanks! I won't merge this for 1.6.0 btw, that's 1.6.1 material

Good call, will give us time to think about it a bit. I'm still concern about having to wait 5 second if you stop the main loop before GstPlayer.
Comment 15 Sebastian Dröge (slomo) 2015-09-25 20:17:51 UTC
You don't have to wait for GstPlayer, because on shutdown we only dispatch to the main context *if* gtksink created its own window :)
Comment 16 Nicolas Dufresne (ndufresne) 2015-09-25 21:27:17 UTC
Except for:

http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/ext/gtk/gstgtkbasesink.c#n146

The last ref to the pipeline need to be triggered by the main thread here (or we need a dispatch to main thread, which is problematic).
Comment 17 Tim-Philipp Müller 2018-01-14 20:39:52 UTC
What's up with this now?
Comment 18 Nicolas Dufresne (ndufresne) 2018-01-15 01:47:31 UTC
Maybe we should have written code to demonstrate the issue in the first place ?
Comment 19 Sebastian Dröge (slomo) 2018-05-06 15:21:17 UTC
Let's get rid of this bug for the time being then until there is an actual problem someone can reproduce.