how to make sure bus messages expected/received?

Chuck Crisler ccrisler at mutualink.net
Fri Jun 13 06:14:35 PDT 2014


If it is that critical that you handle these messages, then you could
signal when the receiving thread is ready using some shared object, even a
shared boolean.


On Fri, Jun 13, 2014 at 9:03 AM, Sergei Vorobyov <
sergei.vorobyov at facilitylabs.com> wrote:

> Thanks, Tim!
>
> Imagine your code is a part of a bigger loop (as I said):
>
> for (;;) {
>   msg = gst_bus_timed_pop_filtered(...)
>   while (msg) {
>     handle_message (msg);
>     gst_message_unref (msg);
>     msg = gst_bus_pop (bus);
>   }
> }
>
> Suppose while you are handling msg in the while loop the other thread
> posts a message on the bus. It turns out that this message is not expected
> nor handled (the blocking msg =  gst_bus_timed_pop_filtered is not active).
> [This is bad, especially in real-time applications.]
>
> How could I figure in the other thread that the message is being expected,
> i.e., stays in the blocking msg = gst_bus_timed_pop_filtered(...)?
>
> Of course, this is a general synchronization problem, but I though
> GStreamer had special APIs or idioms for this common problem. This would be
> possible, if, e.g.,  gst_bus_post (bus, ...) returned more meaningful
> (than just boolean) return codes.
>
> I suggested surrounding by flush OFF/ON since this (almost) allows the
> other thread to check whether its posting is expected or not (by boolean
> result), and repeat (and/or taking other actions) until it is.
>
> BTW, if you post a message on the bus no one is listening to, does it
> disappear or remains until someone starts to listen for this kind of
> messages on the bus?
>
>
> On Fri, Jun 13, 2014 at 2:15 PM, Tim Müller <tim at centricular.com> wrote:
>
>> 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
>>
>> _______________________________________________
>> 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/20140613/52b3c414/attachment-0001.html>


More information about the gstreamer-devel mailing list