Threads in general

Within thread tree context you have to take care not to hang it up with a dead-lock. Usually you have to use the :start_queue to start threads. Protect it with :start_mutex. Alternatively you may want to use void ags_thread_start(AgsThread*). The :start_cond notifies about thread being started.

The following example creates a thread and does add an other thread to :start_queue. This causes it to be started as well. Note you want to access :start_queue using atomic operations since it is volatile. But there is a convience function which does it for you.

Example 3.1. Starting threads

#include <glib.h>
#include <glib-object.h>

#include <ags/libags.h>

AgsThread *main_loop;
AgsThread *thread;

AgsApplicationContext *application_context;

application_context = ags_application_context_get_instance();

main_loop = ags_generic_main_loop_new(application_context);
g_object_set(application_context,
             "main-loop", main_loop,
             NULL);

ags_thread_start(main_loop);

thread = ags_thread_new(NULL);
ags_thread_add_child_extended(main_loop,
                              thread,
                              TRUE, TRUE);
ags_thread_add_start_queue(main_loop,
			   thread);

      

There many other functions not covered like mutex wrappers ags_thread_lock() and ags_thread_unlock(). As doing a closer look to the API there are functions to lock different parts of the tree. But all these functions should be carefully used, since you might run into a dead-lock.

ags_thread_resume() and ags_suspend() wakes-up or suspends threads. But they both should be used within same tic of ::clock. ags_thread_timelock() is used for suspending computing expensive threads and passing ::clock within its run.

To find a specific thread type use ags_thread_find(). You can use ags_thread_self() to retrieve your own running thread in case your using Advanced Gtk+ Sequencer thread wrapper.