Handling race conditions with g_main_loop_run and g_main_loop_quit

Jan Alexander Steffens jan.steffens at gmail.com
Tue Aug 15 14:50:51 UTC 2017


On Tue, Aug 15, 2017, 16:36 jml5qh <jml5qh at gmail.com> wrote:

> Hi all,
>
> I have a streaming application where the user can play and stop the stream.
> When the user presses play, create a new pthread to setup the pipelines and
> call g_main_loop_run:
>
> void GStreamerStreamImpl::start() {
>         pthread_create(&pipeline_setup_thread, NULL, &startInternal, this);
> }
>
> void GStreamerStreamImpl::setupPipelines() {
>         context = g_main_context_new();
>         g_main_context_push_thread_default(context);
>         this->createPipelines(); //Internally call gst_parse_launch on the
> pipeline
>         main_loop = g_main_loop_new(context, FALSE);
>         this->startPlayingPipelines(); //Internally call
> gst_element_set_state with GST_STATE_PLAYING
>         //Now we run the main loop. This will block until the streaming is
> finished
>         g_main_loop_run(main_loop);
>         this->stopPlayingAndDeallocPipelines();
>         g_main_loop_unref (main_loop);
>         main_loop = NULL;
>
>         /* Free resources */
>         g_main_context_pop_thread_default(context);
>         g_main_context_unref (context);
>     }
>
> When the user presses stop, we just call g_main_loop_quit:
>
> void GStreamerStreamImpl::stop()
>     {
>             g_main_loop_quit(main_loop); //This will release the main_loop
> and then everything will get cleaned up
>             pthread_join(pipeline_setup_thread, NULL);
>     }
>
> However, we are running into a race condition if we call g_main_loop_quit
> before the new thread gets to g_main_loop_run. How would you expect to
> handle this? We can check g_main_loop_is_running in stop(), but we still
> need to make sure everything gets cleaned up once the main_loop starts
> running. Ideally, I would just call g_main_loop_quit on the streaming
> thread
> but that's not possible since g_main_loop_run blocks that thread.
>

Use g_main_context_invoke to create an idle source with a callback that
calls g_main_loop_quit. It will be called by the mainloop.

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20170815/4fca0606/attachment.html>


More information about the gstreamer-devel mailing list