how to make sure bus messages expected/received?

Tim Müller tim at centricular.com
Fri Jun 13 05:15:56 PDT 2014


On Fri, 2014-06-13 at 13:47 +0200, Sergei Vorobyov wrote:

Hi Sergei,

> Sorry for a simple question, I could do it by using mutexes, of
> course, but maybe there is a canonical way of doing it using the
> GStreamer APIs?
> 
> 
> The problem is this.
> 
> 
> 1. In one thread, periodically, in the loop, I am waiting for a
> message on the bus:
> 
> 
> msg = gst_bus_timed_pop_filtered (bus, duration,
> 
> (GstMessageType)(GST_MESSAGE_EOS | 
> 
>  GST_MESSAGE_SEGMENT_DONE | 
> 
>  GST_MESSAGE_ERROR | 
> 
>  GST_MESSAGE_APPLICATION));
> 
> 
> and this waiting occupies only part of the whole loop:
> 
> 
> for(;;) {
>   // do smth else...
> 
> 
>   msg = gst_bus_timed_pop_filtered...
> 
> 
>   // do smth else ...
> }
> 
> 
> In the other thread I am posting (using the GStreamer's gift):
> 
> 
> gst_bus_post (bus, gst_message_new_application (NULL, NULL));
> 
> 
> 
> But how can I make sure, before posting, that it is being expected
> (and received) by the blocking
> 
> 
> msg = gst_bus_timed_pop_filtered... in the other thread,
> 
> 
> 
> and not consumed by the loop doing smth else?
> 
> 
> Actually, the boolean TRUE returned by gst_bus_post does not guarantee
> that the posting was expected and received.
> 
> 
> One might naively think that the following is a solution (simply
> surround with gst_bus_set_flushing):
> 
> 
> for(;;) {
>   // do smth else...
> 
> 
>   gst_bus_set_flushing (bus, FALSE);
>   msg = gst_bus_timed_pop_filtered...
>   gst_bus_set_flushing (bus, TRUE);
> 
> 
>   // do smth else ...
> }
> 
> 
> However, it isn't. Imagine gst_bus_timed_pop_filtered returns because
> duration expired, but before the next gst_bus_set_flushing (bus, TRUE)
> the other thread makes gst_bus_post (bus, gst_message_new_application
> (NULL, NULL)). Then this posting is acknowledged (returns TRUE) but
> the message is actually flushed.
> 
> 
> Some real acknowledge mechanism is desired. Does it exist in the
> GStreamer API?

It's not entirely clear to me what you're trying to achieve, if you want
to make sure in your element that the message was actually processed
(and maybe block until then), or if you're having trouble picking up the
message in your other thread.

In you sample code you would probably want to do something like:

  msg = gst_bus_timed_pop_filtered(...)
  while (msg) {
    handle_message (msg);
    gst_message_unref (msg);
    msg = gst_bus_pop (bus);
  }

to make sure that if there's a message you get all pending messages off
in one go before you do something else.

Flushing the bus is a bit weird IMHO and should probably only be done in
special circumstances.

 Cheers
  -Tim

-- 
Tim Müller, Centricular Ltd - http://www.centricular.com



More information about the gstreamer-devel mailing list