Socket file descriptor leaks with GstBus

Duzy Chan geek at duzy.info
Thu Feb 7 04:02:43 PST 2013


I looked into gst_element_set_state, and found:

 * State changes to %GST_STATE_READY or %GST_STATE_NULL never return
 * #GST_STATE_CHANGE_ASYNC.

So I'm understanding this as: "when gst_element_set_state(pipeline,
GST_STATE_NULL) returns, the state of the pipeline should be
GST_STATE_NULL", and it looks like it is so according to my test:

ret = gst_element_get_state (worker->pipeline, &state, NULL,
    GST_CLOCK_TIME_NONE);
 g_assert (ret == GST_STATE_CHANGE_SUCCESS);
g_assert (state == GST_STATE_NULL);

And also I found the auto-flushing in gstpipeline.c code (which is in the
GST_STATE_CHANGE_READY_TO_NULL state change handler of GstPipeline):

      // gstpipeline.c:503
      if (bus) {
        if (auto_flush) {
          gst_bus_set_flushing (bus, TRUE);
        } else {
          GST_INFO_OBJECT (element, "not flushing bus, auto-flushing
disabled");
        }
        gst_object_unref (bus);
      }

And gst_bus_set_flushing is just *discarding* all undispatched messages by:

    // gstbus.c:452
    while ((message = gst_bus_pop (bus)))
      *gst_message_unref* (message);

Which means when we do the following statements on a auto-flush enabled
pipeline:

gst_element_set_state (pipeline, GST_STATE_NULL);

All undispatched messages are supposed to be discarded, instead of flushing
to the installed bus watcher, say:

  worker->bus = gst_pipeline_get_bus (GST_PIPELINE (worker->pipeline));
  worker->watch = *gst_bus_add_watch* (worker->bus,
      (GstBusFunc) *gst_worker_message*, worker);

I suppose that auto-flush should dispatch the pended messages to the
watcher gst_worker_message instead of just discarding the them when we're
just setting the pipeline state to NULL. Because when setting the state to
NULL, the watcher is still there expecting to see the messages it should
see.

So I'm think that gst_bus_set_flushing is not safe by just
gst_message_unref undispatched messages in the case of auto-flush enabled
pipelines. It's not gst_bus_discard. And I'm think that the
gst_bus_set_flushing should be something like:

// gstbus.c:452

while ((message = gst_bus_pop (bus))

    *send_message_to_the_installed_watchers* (message);

Instead of just gst_message_unref them. Because I think I'm setting a
pipeline to NULL, the watcher is expecting to get a
GST_STATE_CHANGE_READY_TO_NULL, or it's risky as an application writer to
produce buggy stuffs.

Best Regards Sincerely
Duzy Chan


On Thu, Feb 7, 2013 at 7:00 PM, Tim-Philipp Müller <t.i.m at zen.co.uk> wrote:

> On Thu, 2013-02-07 at 17:12 +0800, Duzy Chan wrote:
>
>
> > It looks like the GST_STATE_CHANGE_READY_TO_NULL message was not
> > issued while I was stopping the worker (setting the pipeline to
> > GST_STATE_NULL). Yet the state did changed into NULL (according to
> > gst_element_get_state). I'm wondering if I was doing something wrong.
>
> That is entirely expected.
>
> >          see:
> >
> https://github.com/duzy/gst-switch/blob/master/tools/gstworker.c#L629
> >         gst_pipeline_set_auto_flush_bus (GST_PIPELINE
> >         (worker->pipeline), FALSE);
> >
> > I got the expected GST_STATE_CHANGE_READY_TO_NULL state change
> > message.
> >
> > Do you guys have some ideas on this? I assume I should have missed
> > something.
>
> See the documentation for gst_pipeline_set_auto_flush_bus():
>
>
> http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPipeline.html#gst-pipeline-set-auto-flush-bus
>
> "Usually, when a pipeline goes from READY to NULL state, it
> automatically flushes all pending messages on the bus, which is done for
> refcounting purposes, to break circular references.
>
> This means that applications that update state using (async) bus
> messages (e.g. do certain things when a pipeline goes from PAUSED to
> READY) might not get to see messages when the pipeline is shut down,
> because they might be flushed before they can be dispatched in the main
> thread. This behaviour can be disabled using this function.
>
> It is important that all messages on the bus are handled when the
> automatic flushing is disabled else memory leaks will be introduced."
>
> Cheers
>  -Tim
>
> >
> > On Thu, Feb 7, 2013 at 9:12 AM, Duzy Chan <geek at duzy.info> wrote:
> >
> >
> >
> >         On Thu, Feb 7, 2013 at 6:17 AM, David Schleef <ds at schleef.org>
> >         wrote:
> >                 On Wed, Feb 06, 2013 at 06:40:08PM +0800, Duzy Chan
> >                 wrote:
> >                 > On Wed, Feb 6, 2013 at 6:22 PM, Tim-Philipp Müller
> >                 <t.i.m at zen.co.uk> wrote:
> >                 >
> >
> >                 > > Yes, I did check that out and did look at it, but
> >                 I'm afraid I don't
> >                 > > really have time to look at all that in detail,
> >                 hence the request for
> >                 > > something stand-alone and minimal. If it's an
> >                 issue with pipeline
> >                 > > creation / GstBus / watch usage, it shouldn't be
> >                 too hard to re-create.
> >                 > >
> >                 >
> >                 > I would like to do a bit effort to make a stand
> >                 alone minimal test case of
> >                 > the GstBus usage, and see if we can duplicate the
> >                 same issue to help to
> >                 > find out the reason.
> >                 >
> >
> >
> >                 The first thing you should check is that you are
> >                 properly cleaning
> >                 up all your objects.  If you leak a pipeline, object,
> >                 or bus, you'll
> >                 end up with multiple copies of intervideosrc around,
> >                 which will
> >                 use file descriptors.
> >
> >
> >         I hacked a bit into intervideosrc, but it looks like the inter
> >         elements are all memory based, which I think should be
> >         in-process available, without allocating a file descriptor,
> >         all memory based utilities: list, buffer, mutex.
> >
> >
> >         Now I'm thinking that if there're any messages which holding
> >         the references of the pipeline, and when I unref-ed the
> >         pipeline, somehow caused cycling-referencing (my guess).
> >         Because in per cycle reset of the pipeline, I did
> >         g_source_remove the watch, gst_object_unref the bus, null and
> >         gst_object_unref the pipeline.
> >
> >
> >         I tried to make my reset function (say gst_worker_reset)
> >         none-operation (which I commented out all, leaving a "result =
> >         TRUE"), and the file descriptor leaks gone.
> >
> >
> >         So I'm guessing it's somehow getting cycling-referencing or I
> >         did forgot to unref something.
> >
> >
> >         I'll spend some time to play around the stand-alone test code
> >         to try to duplicate the execution flow in minimal. And also
> >         check further.
> >
> >
> >
> >
> >                 David
> >
> >                 _______________________________________________
> >                 gstreamer-devel mailing list
> >                 gstreamer-devel at lists.freedesktop.org
> >
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
> >
> >
> >
> >
> >
> > _______________________________________________
> > gstreamer-devel mailing list
> > gstreamer-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20130207/d2a38eaf/attachment.html>


More information about the gstreamer-devel mailing list