GNOME Bugzilla – Bug 732866
udpsink: client add/remove from app blocked while render function is stuck in g_socket_send_message()
Last modified: 2014-12-16 20:34:21 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().
Also see the patches in bug #732152 which change the locking (I don't think what the current code does is right).
Tim-Philipp, I tested out your patches from bug #732152 and I have not seen the dead-lock issue again. Thanks!
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.
Author: Tim-Philipp Müller <firstname.lastname@example.org>
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.