Handling race conditions with g_main_loop_run and g_main_loop_quit

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Handling race conditions with g_main_loop_run and g_main_loop_quit

jml5qh
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.
Reply | Threaded
Open this post in threaded view
|

Re: Handling race conditions with g_main_loop_run and g_main_loop_quit

Jan Alexander Steffens


On Tue, Aug 15, 2017, 16:36 jml5qh <[hidden email]> 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.

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel