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 688852 - udpsrc recvfrom() block fix
udpsrc recvfrom() block fix
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
0.10.36
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2012-11-22 06:27 UTC by Markovtsev Vadim
Modified: 2013-08-14 11:11 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Markovtsev Vadim 2012-11-22 06:27:36 UTC
gst/udp/gstudpsrc.c, near line 495:

  /* If we get here and the readsize is zero, then either select was woken up
   * by activity that is not a read, or a poll error occurred, or a UDP packet
   * was received that has no data. Since we cannot identify which case it is,
   * we handle all of them. This could possibly lead to a UDP packet getting
   * lost, but since UDP is not reliable, we can accept this. */
  if (G_UNLIKELY (!readsize)) {
    /* try to read a packet (and it will be ignored),
     * in case a packet with no data arrived */
    slen = sizeof (sa);
    recvfrom (udpsrc->sock.fd, (char *) &slen, 0, 0, &sa.sa, &slen);

    /* clear any error, in case a poll error occurred */
    clear_error (udpsrc);

    /* poll again */
    goto retry;
  }

If a poll error occurs (for example, connection is lost), recvfrom() sometimes blocks on recvfrom() forever. Since LIVE_LOCK() is previously taken, any attempt to set udpsrc state from PLAYING to PAUSED hangs on LIVE_LOCK() then. This prevents from successful destroying of udpsrc when the other end dies at the same time (this deadlock floats, sometimes it happens and sometimes everything's OK).

I suggest to add MSG_DONTWAIT to flags, so that in case of errors that would block recvfrom(), it goes on without blocking:

recvfrom (udpsrc->sock.fd, (char *) &slen, 0, MSG_DONTWAIT, &sa.sa, &slen)
Comment 1 Wim Taymans 2012-11-22 11:53:46 UTC
This has been rewritten in 1.0. I would like to mark this obsolete, there is not going to be any 0.10 release anymore.
Comment 2 Markovtsev Vadim 2012-11-22 14:05:19 UTC
Please note that in 1.0 this part was rewritten using g_socket_receive_from() with GCancellable, hope it is fixed now.
Comment 3 Tim-Philipp Müller 2012-11-23 00:35:45 UTC
It would be great if you could check that and confirm it.

I don't see MSG_DONTWAIT in the g_socket_receive_message() code, nor am I sure the socket is made non-blocking anywhere.
Comment 4 Edward Hervey 2013-08-14 08:11:53 UTC
Tim, you mean confirm for 1.0 or for 0.10 ? If it's for 0.10, let's just close this.
Comment 5 Sebastian Dröge (slomo) 2013-08-14 08:51:27 UTC
He is talking about GIO, so 1.0. But let's close it as no feedback was provided in a long time and in theory GSocket should do things properly in that regard.
Comment 6 Markovtsev Vadim 2013-08-14 11:11:01 UTC
Sorry guys, I am no longer working on the related project. Looks like it is better to leave this closed.