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 734716 - bus: signal watched added in a new thread-default context can't be removed
bus: signal watched added in a new thread-default context can't be removed
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other Linux
: Normal normal
: 1.5.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-08-13 11:28 UTC by Philippe Normand
Modified: 2014-08-13 15:46 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch (1.44 KB, patch)
2014-08-13 12:22 UTC, Philippe Normand
needs-work Details | Review
bus: destroy signal watch from the context it was mapped to (3.42 KB, patch)
2014-08-13 15:06 UTC, Philippe Normand
needs-work Details | Review
bus: destroy signal watch from the context it was mapped to (3.38 KB, patch)
2014-08-13 15:41 UTC, Philippe Normand
committed Details | Review

Description Philippe Normand 2014-08-13 11:28:22 UTC
The watch is attached to the current thread-default main context but gst_bus_remove_signal_watch() invokes g_source_remove() which operates on the default main context.

So in that configuration the source won't be removed and GLib emits a critical warning.

I think the solution would be to get the thread-default context in _remove_signal_watch(), look for the source in that context and destroy it. I'll post a patch :)
Comment 1 Sebastian Dröge (slomo) 2014-08-13 11:35:43 UTC
(In reply to comment #0)

> I think the solution would be to get the thread-default context in
> _remove_signal_watch(), look for the source in that context and destroy it.
> I'll post a patch :)

No, you'll have to remember the main context that was the default when the watch was added :) To get around this I just called g_source_destroy() in the past.
Comment 2 Philippe Normand 2014-08-13 11:38:43 UTC
(In reply to comment #1)
> (In reply to comment #0)
> 
> > I think the solution would be to get the thread-default context in
> > _remove_signal_watch(), look for the source in that context and destroy it.
> > I'll post a patch :)
> 
> No, you'll have to remember the main context that was the default when the
> watch was added :)

Oh right, in my code I remove the signal watch before popping the thread-default context but we can't assume everyone would do that :)

> To get around this I just called g_source_destroy() in the
> past.

Alright, do you know why that code was changed?
Comment 3 Philippe Normand 2014-08-13 12:22:34 UTC
Created attachment 283280 [details] [review]
Patch
Comment 4 Sebastian Dröge (slomo) 2014-08-13 12:36:31 UTC
Review of attachment 283280 [details] [review]:

::: gst/gstbus.c
@@ +1317,3 @@
 gst_bus_remove_signal_watch (GstBus * bus)
 {
+  GSource *source = 0;

Use NULL instead of 0

@@ +1333,3 @@
 
+  GST_DEBUG_OBJECT (bus, "removing signal watch %u",
+      bus->priv->signal_watch_id);

%p

@@ +1337,2 @@
+  bus->priv->signal_watch_id = 0;
+  source = bus->priv->watch_id;

And change the priv->watch_id guint to a GSource * and make sure to actually store the GSource there instead of the return value of attach(). And also unref the source after you're done with it, not just destroy it.
Comment 5 Philippe Normand 2014-08-13 15:06:30 UTC
Created attachment 283291 [details] [review]
bus: destroy signal watch from the context it was mapped to

Don't rely on g_source_remove() because it operates on the main
context. If a signal watch was added to a new thread-default context
g_source_remove() would have no effect. So simply use
g_source_destroy() to avoid this problem.

Additionally the source_id was removed from GstBusPrivate because it
was redundant with the signal watch GSource also stored in that
structure.
Comment 6 Sebastian Dröge (slomo) 2014-08-13 15:16:25 UTC
Comment on attachment 283291 [details] [review]
bus: destroy signal watch from the context it was mapped to

valgrind is not happy in the unit test:

Running suite(s): GstBus
==16859== Invalid read of size 8
==16859==    at 0x5A4E835: g_source_unref (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==16859==    by 0x403635: test_watch_with_poll (gstbus.c:397)
==16859==    by 0x4E40D52: srunner_run_all (check_run.c:372)
==16859==    by 0x4E3AF60: gst_check_run_suite (gstcheck.c:817)
==16859==    by 0x402E78: main (gstbus.c:729)
==16859==  Address 0x6cd19e0 is 32 bytes inside a block of size 104 free'd
==16859==    at 0x4C29730: free (vg_replace_malloc.c:468)
==16859==    by 0x5A4D0A7: g_source_unref_internal (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==16859==    by 0x5A4D458: g_source_destroy_internal (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==16859==    by 0x52E85B4: gst_bus_remove_signal_watch (gstbus.c:1341)
==16859==    by 0x403635: test_watch_with_poll (gstbus.c:397)
==16859==    by 0x4E40D52: srunner_run_all (check_run.c:372)
==16859==    by 0x4E3AF60: gst_check_run_suite (gstcheck.c:817)
==16859==    by 0x402E78: main (gstbus.c:729)
==16859== 
==16859== Invalid read of size 4
==16859==    at 0x5A4D0E8: g_source_unref_internal (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==16859==    by 0x403635: test_watch_with_poll (gstbus.c:397)
==16859==    by 0x4E40D52: srunner_run_all (check_run.c:372)
==16859==    by 0x4E3AF60: gst_check_run_suite (gstcheck.c:817)
==16859==    by 0x402E78: main (gstbus.c:729)
==16859==  Address 0x6cd19d8 is 24 bytes inside a block of size 104 free'd
==16859==    at 0x4C29730: free (vg_replace_malloc.c:468)
==16859==    by 0x5A4D0A7: g_source_unref_internal (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==16859==    by 0x5A4D458: g_source_destroy_internal (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==16859==    by 0x52E85B4: gst_bus_remove_signal_watch (gstbus.c:1341)
==16859==    by 0x403635: test_watch_with_poll (gstbus.c:397)
==16859==    by 0x4E40D52: srunner_run_all (check_run.c:372)
==16859==    by 0x4E3AF60: gst_check_run_suite (gstcheck.c:817)
==16859==    by 0x402E78: main (gstbus.c:729)
==16859==
Comment 7 Philippe Normand 2014-08-13 15:32:27 UTC
Ah it's due to the _unref after _destroy. Will update the patch!
Comment 8 Philippe Normand 2014-08-13 15:41:35 UTC
Created attachment 283296 [details] [review]
bus: destroy signal watch from the context it was mapped to

Don't rely on g_source_remove() because it operates on the main
context. If a signal watch was added to a new thread-default context
g_source_remove() would have no effect. So simply use
g_source_destroy() to avoid this problem.

Additionally the source_id was removed from GstBusPrivate because it
was redundant with the signal watch GSource also stored in that
structure.
Comment 9 Sebastian Dröge (slomo) 2014-08-13 15:46:46 UTC
commit b1f23598099da82835df60bc2fb09501233f9118
Author: Philippe Normand <philn@igalia.com>
Date:   Wed Aug 13 14:12:00 2014 +0200

    bus: destroy signal watch from the context it was mapped to
    
    Don't rely on g_source_remove() because it operates on the main
    context. If a signal watch was added to a new thread-default context
    g_source_remove() would have no effect. So simply use
    g_source_destroy() to avoid this problem.
    
    Additionally the source_id was removed from GstBusPrivate because it
    was redundant with the signal watch GSource also stored in that
    structure.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=734716