[gstreamer-bugs] [Bug 473846] New: Deadlock if sink is unable to send first buffer

GStreamer (bugzilla.gnome.org) bugzilla-daemon at bugzilla.gnome.org
Wed Sep 5 02:07:24 PDT 2007


If you have any questions why you received this email, please see the text at
the end of this email. Replies to this email are NOT read, please see the text
at the end of this email. You can add comments to this bug at:
  http://bugzilla.gnome.org/show_bug.cgi?id=473846

  GStreamer | gstreamer (core) | Ver: 0.10.13
           Summary: Deadlock if sink is unable to send first buffer
           Product: GStreamer
           Version: 0.10.13
          Platform: Other
        OS/Version: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: Normal
         Component: gstreamer (core)
        AssignedTo: gstreamer-bugs at lists.sourceforge.net
        ReportedBy: johan.gyllenspetz at axis.com
         QAContact: gstreamer-bugs at lists.sourceforge.net
     GNOME version: Unspecified
   GNOME milestone: Unspecified


Please describe the problem:
Unlock function is not called on a sink that sink is based on basesink. This
occurs when that sink is added to an pipeline that is already in PLAY state
(the sink is brought up to PLAY before it is added) and the sink is unable to
pass on its first buffer (i.e. it never returns).

Steps to reproduce:
1. Add a source to a pipeline
2. Set the pipeline to PLAYING state
3. Create a sink (based on basesink) that does not return in render.
4. Set the state of the sink to PLAYING
5. Add sink to pipeline.
6. Try to set state of pipeline to NULL
7. App will hang on STATE_LOCK


Actual results:
1. The GST_PAD_PREROLL_LOCK for the sink is taken in gst_base_sink_chain,
initiated by a gst_pad_push.
2. Since the sink is unable to push its first buffer the lock will not be
released.
3. The GST_STATE_LOCK for the pipeline is taken in gst_bin_continue_func which
then performs a latency query and then hangs on the sinks GST_PAD_PREROLL_LOCK
(taken in 1.).
4. When the state is changed to NULL the gst_element_set_state_func will hang
on on the previously taken GST_STATE_LOCK.

Expected results:
A deadlock occurs.

Does this happen every time?
yes

Other information:
/*
 * A small test application that simulates the bug with an fdsink writing more
 * then 64K to a pipe and therefore blocks the first buffer.
 */

#include <gst/gst.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int
main (int   argc,
      char *argv[])
{
  GstStateChangeReturn sret;
  GstElement *pipeline;
  GstElement *source, *sink;
  gint fd;

  gst_init (&argc, &argv);

  if (unlink("test")) {
    perror("unlink:");
  }

  if (mkfifo("test", O_CREAT|S_IRWXU)) {
    perror("mkfifo:");
  }

  fd = open("test", O_RDWR);

  pipeline = gst_pipeline_new ("pipeline");

  source = gst_element_factory_make ("fakesrc", "source");

  g_object_set (G_OBJECT (source), "num-buffers", 5, NULL);
  g_object_set (G_OBJECT (source), "sizetype", 2, NULL);
  g_object_set (G_OBJECT (source), "filltype", 4, NULL);
  g_object_set (G_OBJECT (source), "sizemax", 70000, NULL);

  gst_bin_add (GST_BIN (pipeline), source);

  sret = gst_element_set_state (pipeline, GST_STATE_PLAYING);

  sink = gst_element_factory_make ("fdsink", "sink");
  g_object_set (G_OBJECT (sink), "fd",
                fd,
                NULL);

  gst_bin_add (GST_BIN (pipeline), sink);

  gst_element_set_state (sink, GST_STATE_PLAYING);

  gst_element_link (source, sink);

  /* To make sure that the deadlock occurs */
  sleep (4);

  gst_element_set_state (pipeline, GST_STATE_NULL);

  return 0;
}


-- 
See http://bugzilla.gnome.org/page.cgi?id=email.html for more info about why you received
this email, why you can't respond via email, how to stop receiving
emails (or reduce the number you receive), and how to contact someone
if you are having problems with the system.

You can add comments to this bug at http://bugzilla.gnome.org/show_bug.cgi?id=473846.




More information about the Gstreamer-bugs mailing list