AsyncQueue

Often you need to communicate between different threads. In general it's safer not to do this by shared memory, but by explicit message passing. These messages only make sense asynchronously for multi-threaded applications though, as a synchronous operation could as well be done in the same thread.

Asynchronous queues are an exception from most other GLib data structures, as they can be used simultaneously from multiple threads without explicit locking and they bring their own builtin reference counting. This is because the nature of an asynchronous queue is that it will always be used by at least 2 concurrent threads.

For using an asynchronous queue you first have to create one with g_async_queue_new(). GAsyncQueue structs are reference counted, use g_async_queue_ref() and g_async_queue_unref() to manage your references.

A thread which wants to send a message to that queue simply calls g_async_queue_push() to push the message to the queue.

A thread which is expecting messages from an asynchronous queue simply calls g_async_queue_pop() for that queue. If no message is available in the queue at that point, the thread is now put to sleep until a message arrives. The message will be removed from the queue and returned. The functions g_async_queue_try_pop() and g_async_queue_timeout_pop() can be used to only check for the presence of messages or to only wait a certain time for messages respectively.

For almost every function there exist two variants, one that locks the queue and one that doesn't. That way you can hold the queue lock (acquire it with g_async_queue_lock() and release it with g_async_queue_unlock()) over multiple queue accessing instructions. This can be necessary to ensure the integrity of the queue, but should only be used when really necessary, as it can make your life harder if used unwisely. Normally you should only use the locking function variants (those without the _unlocked suffix).

In many cases, it may be more convenient to use GThreadPool when you need to distribute work to a set of worker threads instead of using GAsyncQueue manually. GThreadPool uses a GAsyncQueue internally.

Constructors

this
this(GAsyncQueue* gAsyncQueue)

Sets our main struct and passes it to the parent class

this
this()

Creates a new asynchronous queue.

this
this(GDestroyNotify itemFreeFunc)

Creates a new asynchronous queue and sets up a destroy notify function that is used to free any remaining queue items when the queue is destroyed after the final unref. Since 2.16

Members

Functions

doref
AsyncQueue doref()

Increases the reference count of the asynchronous queue by 1. You do not need to hold the lock to call this function.

getAsyncQueueStruct
GAsyncQueue* getAsyncQueueStruct()

Get the main Gtk struct

getStruct
void* getStruct()

the main Gtk struct as a void*

length
int length()

Returns the length of the queue. Actually this function returns the number of data items in the queue minus the number of waiting threads, so a negative value means waiting threads, and a positive value means available entries in the queue. A return value of 0 could mean n entries in the queue and n threads waiting. This can happen due to locking of the queue or due to scheduling.

lengthUnlocked
int lengthUnlocked()

Returns the length of the queue. Actually this function returns the number of data items in the queue minus the number of waiting threads, so a negative value means waiting threads, and a positive value means available entries in the queue. A return value of 0 could mean n entries in the queue and n threads waiting. This can happen due to locking of the queue or due to scheduling. This function must be called while holding the queue's lock.

lock
void lock()

Acquires the queue's lock. If another thread is already holding the lock, this call will block until the lock becomes available. Call g_async_queue_unlock() to drop the lock again. While holding the lock, you can only call the g_async_queue_*_unlocked() functions on queue. Otherwise, deadlock may occur.

pop
void* pop()

Pops data from the queue. If queue is empty, this function blocks until data becomes available.

popUnlocked
void* popUnlocked()

Pops data from the queue. If queue is empty, this function blocks until data becomes available. This function must be called while holding the queue's lock.

push
void push(void* data)

Pushes the data into the queue. data must not be NULL.

pushSorted
void pushSorted(void* data, GCompareDataFunc func, void* userData)

Inserts data into queue using func to determine the new position. This function requires that the queue is sorted before pushing on new elements, see g_async_queue_sort(). This function will lock queue before it sorts the queue and unlock it when it is finished. For an example of func see g_async_queue_sort(). Since 2.10

pushSortedUnlocked
void pushSortedUnlocked(void* data, GCompareDataFunc func, void* userData)

Inserts data into queue using func to determine the new position. The sort function func is passed two elements of the queue. It should return 0 if they are equal, a negative value if the first element should be higher in the queue or a positive value if the first element should be lower in the queue than the second element. This function requires that the queue is sorted before pushing on new elements, see g_async_queue_sort(). This function must be called while holding the queue's lock. For an example of func see g_async_queue_sort(). Since 2.10

pushUnlocked
void pushUnlocked(void* data)

Pushes the data into the queue. data must not be NULL. This function must be called while holding the queue's lock.

refUnlocked
void refUnlocked()

Warning g_async_queue_ref_unlocked has been deprecated since version 2.8 and should not be used in newly-written code. Reference counting is done atomically. so g_async_queue_ref() can be used regardless of the queue's lock. Increases the reference count of the asynchronous queue by 1.

sort
void sort(GCompareDataFunc func, void* userData)

Sorts queue using func. The sort function func is passed two elements of the queue. It should return 0 if they are equal, a negative value if the first element should be higher in the queue or a positive value if the first element should be lower in the queue than the second element. This function will lock queue before it sorts the queue and unlock it when it is finished. If you were sorting a list of priority numbers to make sure the Since 2.10

sortUnlocked
void sortUnlocked(GCompareDataFunc func, void* userData)

Sorts queue using func. The sort function func is passed two elements of the queue. It should return 0 if they are equal, a negative value if the first element should be higher in the queue or a positive value if the first element should be lower in the queue than the second element. This function must be called while holding the queue's lock. Since 2.10

timedPop
void* timedPop(GTimeVal endTime)

Warning g_async_queue_timed_pop is deprecated and should not be used in newly-written code. use g_async_queue_timeout_pop(). Pops data from the queue. If the queue is empty, blocks until end_time or until data becomes available. If no data is received before end_time, NULL is returned. To easily calculate end_time, a combination of g_get_current_time() and g_time_val_add() can be used.

timedPopUnlocked
void* timedPopUnlocked(GTimeVal endTime)

Warning g_async_queue_timed_pop_unlocked is deprecated and should not be used in newly-written code. use g_async_queue_timeout_pop_unlocked(). Pops data from the queue. If the queue is empty, blocks until end_time or until data becomes available. If no data is received before end_time, NULL is returned. To easily calculate end_time, a combination of g_get_current_time() and g_time_val_add() can be used. This function must be called while holding the queue's lock.

timeoutPop
void* timeoutPop(ulong timeout)

Pops data from the queue. If the queue is empty, blocks for timeout microseconds, or until data becomes available. If no data is received before the timeout, NULL is returned.

timeoutPopUnlocked
void* timeoutPopUnlocked(ulong timeout)

Pops data from the queue. If the queue is empty, blocks for timeout microseconds, or until data becomes available. If no data is received before the timeout, NULL is returned. This function must be called while holding the queue's lock.

tryPop
void* tryPop()

Tries to pop data from the queue. If no data is available, NULL is returned.

tryPopUnlocked
void* tryPopUnlocked()

Tries to pop data from the queue. If no data is available, NULL is returned. This function must be called while holding the queue's lock.

unlock
void unlock()

Releases the queue's lock. Calling this function when you have not acquired the with g_async_queue_lock() leads to undefined behaviour.

unref
void unref()

Decreases the reference count of the asynchronous queue by 1. If the reference count went to 0, the queue will be destroyed and the memory allocated will be freed. So you are not allowed to use the queue afterwards, as it might have disappeared. You do not need to hold the lock to call this function.

unrefAndUnlock
void unrefAndUnlock()

Warning g_async_queue_unref_and_unlock has been deprecated since version 2.8 and should not be used in newly-written code. Reference counting is done atomically. so g_async_queue_unref() can be used regardless of the queue's lock. Decreases the reference count of the asynchronous queue by 1 and releases the lock. This function must be called while holding the queue's lock. If the reference count went to 0, the queue will be destroyed and the memory allocated will be freed.

Variables

gAsyncQueue
GAsyncQueue* gAsyncQueue;

the main Gtk struct

Meta