Threaded Loop

# Overview

The threaded loop implementation is a special wrapper around the regular pw_loop implementation.

The added feature in the threaded loop is that it spawns a new thread that runs the wrapped loop. This allows a synchronous application to use the asynchronous API without risking to stall the PipeWire library.

# Creation

A pw_thread_loop object is created using pw_thread_loop_new(). The pw_loop to wrap must be given as an argument along with the name for the thread that will be spawned.

After allocating the object, the thread must be started with pw_thread_loop_start()

# Destruction

When the PipeWire connection has been terminated, the thread must be stopped and the resources freed. Stopping the thread is done using pw_thread_loop_stop(), which must be called without the lock (see below) held. When that function returns, the thread is stopped and the pw_thread_loop object can be freed using pw_thread_loop_destroy().

# Locking

Since the PipeWire API doesn't allow concurrent accesses to objects, a locking scheme must be used to guarantee safe usage. The threaded loop API provides such a scheme through the functions pw_thread_loop_lock() and pw_thread_loop_unlock().

The lock is recursive, so it's safe to use it multiple times from the same thread. Just make sure you call pw_thread_loop_unlock() the same number of times you called pw_thread_loop_lock().

The lock needs to be held whenever you call any PipeWire function that uses an object associated with this loop. Make sure you do not hold on to the lock more than necessary though, as the threaded loop stops while the lock is held.

# Events and Callbacks

All events and callbacks are called with the thread lock held.