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 732866 - udpsink: client add/remove from app blocked while render function is stuck in g_socket_send_message()
udpsink: client add/remove from app blocked while render function is stuck in...
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other Windows
: Normal normal
: 1.5.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-07-07 20:44 UTC by Jake Foytik
Modified: 2014-12-16 20:34 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Jake Foytik 2014-07-07 20:44:52 UTC
Problem: Testing the rtsp-server on windows using the test-launch example and randomly connecting/disconnecting multiple streams (50) from the server. After several iterations of connecting and disconnecting, the main loop will occasionally enter a dead-locked state. 

I have localized the problem to when an rtsp-server class signals the "remove" action on udpsink. The program will hang indefinitely on this function as it is trying to obtain a lock on a mutex. It is unable to obtain the lock because the gst_multiudpsink_render() function of gstmultiudpsink.c currently has the lock and is stuck on the g_socket_send_message() function.

It appears I am creating some scenario where the g_socket_send_message() is unexpectedly blocking. Reading the gsocket documentation, by default gsockets are configured as blocking and do not have a timeout set. I couldn't find any indication that the socket is configured (as non-blocking or with a timeout) after its creation in udpsink or multiudpsink. Thus, using the gsocket in its default configuration could seemingly allow the send_message() function to hang indefinitely. Looking at gsocket.c, this could happen for one of the following reasons:
 - The socket never indicates it it is ready for writing and the program waits on the g_socket_condition_wait() function.
 - The WSASendTo() function repeatedly returns either a WSAEINTR or WSAEWOULDBLOCK error, allowing the program to stay in the infinite while loop.

Since we are dealing with UDP, would it be appropriate to set the gsocket as non-blocking and allow the send_message function to post an error?

Another option may be to have the gst_multiudpsink_remove() function trigger the cancellable that is passed to send_message().
Comment 1 Tim-Philipp Müller 2014-07-07 21:26:37 UTC
Also see the patches in bug #732152 which change the locking (I don't think what the current code does is right).
Comment 2 Jake Foytik 2014-07-08 15:20:51 UTC
Tim-Philipp, I tested out your patches from bug #732152 and I have not seen the dead-lock issue again. Thanks!
Comment 3 Tim-Philipp Müller 2014-12-16 20:33:05 UTC
Thanks for testing!

There's still a case to be made for making the sockets udpsink operates on non-blocking, but I think that's a separate discussion.

commit dead5c2476ff1033c8765764fbe970a084ad888a
Author: Tim-Philipp Müller <tim@centricular.com>
Date:   Thu Jun 19 19:16:01 2014 +0100

    multiudpsink: make udp client structure refcounted
    
    Use the refcount for memory management and keep track
    of the number of duplicate clients in a separate
    variable. This will be useful later, and means we
    don't have to hold the OBJECT_LOCK all the time.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=732866