async_queues.xml   [plain text]


<refentry id="glib-Asynchronous-Queues">
<refmeta>
<refentrytitle>Asynchronous Queues</refentrytitle>
<manvolnum>3</manvolnum>
<refmiscinfo>GLIB Library</refmiscinfo>
</refmeta>

<refnamediv>
<refname>Asynchronous Queues</refname><refpurpose>asynchronous communication between threads.</refpurpose>
</refnamediv>

<refsynopsisdiv><title>Synopsis</title>

<synopsis>

#include &lt;glib.h&gt;


struct      <link linkend="GAsyncQueue">GAsyncQueue</link>;
<link linkend="GAsyncQueue">GAsyncQueue</link>* <link linkend="g-async-queue-new">g_async_queue_new</link>              (void);
<link linkend="void">void</link>        <link linkend="g-async-queue-ref">g_async_queue_ref</link>               (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="void">void</link>        <link linkend="g-async-queue-unref">g_async_queue_unref</link>             (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="void">void</link>        <link linkend="g-async-queue-push">g_async_queue_push</link>              (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue,
                                             <link linkend="gpointer">gpointer</link> data);
<link linkend="gpointer">gpointer</link>    <link linkend="g-async-queue-pop">g_async_queue_pop</link>               (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="gpointer">gpointer</link>    <link linkend="g-async-queue-try-pop">g_async_queue_try_pop</link>           (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="gpointer">gpointer</link>    <link linkend="g-async-queue-timed-pop">g_async_queue_timed_pop</link>         (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue,
                                             <link linkend="GTimeVal">GTimeVal</link> *end_time);
<link linkend="gint">gint</link>        <link linkend="g-async-queue-length">g_async_queue_length</link>            (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);

<link linkend="void">void</link>        <link linkend="g-async-queue-lock">g_async_queue_lock</link>              (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="void">void</link>        <link linkend="g-async-queue-unlock">g_async_queue_unlock</link>            (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="void">void</link>        <link linkend="g-async-queue-ref-unlocked">g_async_queue_ref_unlocked</link>      (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="void">void</link>        <link linkend="g-async-queue-unref-and-unlock">g_async_queue_unref_and_unlock</link>  (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="void">void</link>        <link linkend="g-async-queue-push-unlocked">g_async_queue_push_unlocked</link>     (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue,
                                             <link linkend="gpointer">gpointer</link> data);
<link linkend="gpointer">gpointer</link>    <link linkend="g-async-queue-pop-unlocked">g_async_queue_pop_unlocked</link>      (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="gpointer">gpointer</link>    <link linkend="g-async-queue-try-pop-unlocked">g_async_queue_try_pop_unlocked</link>  (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
<link linkend="gpointer">gpointer</link>    <link linkend="g-async-queue-timed-pop-unlocked">g_async_queue_timed_pop_unlocked</link>
                                            (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue,
                                             <link linkend="GTimeVal">GTimeVal</link> *end_time);
<link linkend="gint">gint</link>        <link linkend="g-async-queue-length-unlocked">g_async_queue_length_unlocked</link>   (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);
</synopsis>
</refsynopsisdiv>









<refsect1>
<title>Description</title>
<para>
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.
</para>

<para>
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.
</para>

<para>
For using an asynchronous queue you first have to create one with
<link linkend="g-async-queue-new"><function>g_async_queue_new()</function></link>. A newly-created queue will get the reference
count 1. Whenever another thread is creating a new reference of (that
is, pointer to) the queue, it has to increase the reference count
(using <link linkend="g-async-queue-ref"><function>g_async_queue_ref()</function></link>). Also, before removing this reference, the
reference count has to be decreased (using
<link linkend="g-async-queue-unref"><function>g_async_queue_unref()</function></link>). After that the queue might no longer exist so
you must not access it after that point.
</para>

<para>
A thread, which wants to send a message to that queue simply calls
<link linkend="g-async-queue-push"><function>g_async_queue_push()</function></link> to push the message to the queue.
</para>

<para>
A thread, which is expecting messages from an asynchronous queue
simply calls <link linkend="g-async-queue-pop"><function>g_async_queue_pop()</function></link> 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 <link linkend="g-async-queue-try-pop"><function>g_async_queue_try_pop()</function></link> and
<link linkend="g-async-queue-timed-pop"><function>g_async_queue_timed_pop()</function></link> can be used to only check for the presence
of messages or to only wait a certain time for messages respectively.
</para>

<para>
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 <link linkend="g-async-queue-lock"><function>g_async_queue_lock()</function></link> and release it with
<link linkend="g-async-queue-unlock"><function>g_async_queue_unlock()</function></link>) 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 suffix _unlocked)
</para>
</refsect1>

<refsect1>
<title>Details</title>
<refsect2>
<title><anchor id="GAsyncQueue"/>struct GAsyncQueue</title>
<indexterm><primary>GAsyncQueue</primary></indexterm><programlisting>struct GAsyncQueue;</programlisting>
<para>
The <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link> struct is an opaque data structure, which represents
an asynchronous queue. It should only be accessed through the
<function>g_async_queue_*</function> functions.
</para></refsect2>
<refsect2>
<title><anchor id="g-async-queue-new"/>g_async_queue_new ()</title>
<indexterm><primary>g_async_queue_new</primary></indexterm><programlisting><link linkend="GAsyncQueue">GAsyncQueue</link>* g_async_queue_new              (void);</programlisting>
<para>
Creates a new asynchronous queue with the initial reference count of 1.</para>
<variablelist role="params">
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the new <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-ref"/>g_async_queue_ref ()</title>
<indexterm><primary>g_async_queue_ref</primary></indexterm><programlisting><link linkend="void">void</link>        g_async_queue_ref               (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Increases the reference count of the asynchronous <parameter>queue</parameter> by 1. You
do not need to hold the lock to call this function.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-unref"/>g_async_queue_unref ()</title>
<indexterm><primary>g_async_queue_unref</primary></indexterm><programlisting><link linkend="void">void</link>        g_async_queue_unref             (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Decreases the reference count of the asynchronous <parameter>queue</parameter> by 1. If
the reference count went to 0, the <parameter>queue</parameter> will be destroyed and the
memory allocated will be freed. So you are not allowed to use the
<parameter>queue</parameter> afterwards, as it might have disappeared. You do not need to
hold the lock to call this function.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-push"/>g_async_queue_push ()</title>
<indexterm><primary>g_async_queue_push</primary></indexterm><programlisting><link linkend="void">void</link>        g_async_queue_push              (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue,
                                             <link linkend="gpointer">gpointer</link> data);</programlisting>
<para>
Pushes the <parameter>data</parameter> into the <parameter>queue</parameter>. <parameter>data</parameter> must not be <literal>NULL</literal>.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>data</parameter>&nbsp;:</term>
<listitem><simpara> <parameter>data</parameter> to push into the <parameter>queue</parameter>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-pop"/>g_async_queue_pop ()</title>
<indexterm><primary>g_async_queue_pop</primary></indexterm><programlisting><link linkend="gpointer">gpointer</link>    g_async_queue_pop               (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Pops data from the <parameter>queue</parameter>. This function blocks until data become
available.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> data from the queue.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-try-pop"/>g_async_queue_try_pop ()</title>
<indexterm><primary>g_async_queue_try_pop</primary></indexterm><programlisting><link linkend="gpointer">gpointer</link>    g_async_queue_try_pop           (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Tries to pop data from the <parameter>queue</parameter>. If no data is available, <literal>NULL</literal> is
returned.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> data from the queue or <literal>NULL</literal>, when no data is
available immediately.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-timed-pop"/>g_async_queue_timed_pop ()</title>
<indexterm><primary>g_async_queue_timed_pop</primary></indexterm><programlisting><link linkend="gpointer">gpointer</link>    g_async_queue_timed_pop         (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue,
                                             <link linkend="GTimeVal">GTimeVal</link> *end_time);</programlisting>
<para>
Pops data from the <parameter>queue</parameter>. If no data is received before <parameter>end_time</parameter>,
<literal>NULL</literal> is returned.
</para>
<para>
To easily calculate <parameter>end_time</parameter> a combination of <link linkend="g-get-current-time"><function>g_get_current_time()</function></link>
and <link linkend="g-time-val-add"><function>g_time_val_add()</function></link> can be used.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>end_time</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GTimeVal"><type>GTimeVal</type></link>, determining the final time.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> data from the queue or <literal>NULL</literal>, when no data is
received before <parameter>end_time</parameter>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-length"/>g_async_queue_length ()</title>
<indexterm><primary>g_async_queue_length</primary></indexterm><programlisting><link linkend="gint">gint</link>        g_async_queue_length            (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Returns the length of the queue, negative values mean waiting
threads, positive values mean available entries in the
<parameter>queue</parameter>. Actually this function returns the number of data items in
the queue minus the number of waiting threads. Thus a return value
of 0 could mean 'n' entries in the queue and 'n' thread waiting.
That can happen due to locking of the queue or due to
scheduling.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the length of the <parameter>queue</parameter>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-lock"/>g_async_queue_lock ()</title>
<indexterm><primary>g_async_queue_lock</primary></indexterm><programlisting><link linkend="void">void</link>        g_async_queue_lock              (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Acquires the <parameter>queue</parameter>'s lock. After that you can only call the
<function>g_async_queue_*<link linkend="unlocked"><function>_unlocked()</function></link></function> function variants on that
<parameter>queue</parameter>. Otherwise it will deadlock.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-unlock"/>g_async_queue_unlock ()</title>
<indexterm><primary>g_async_queue_unlock</primary></indexterm><programlisting><link linkend="void">void</link>        g_async_queue_unlock            (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Releases the queue's lock.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-ref-unlocked"/>g_async_queue_ref_unlocked ()</title>
<indexterm role="deprecated"><primary>g_async_queue_ref_unlocked</primary></indexterm><programlisting><link linkend="void">void</link>        g_async_queue_ref_unlocked      (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<warning><para><literal>g_async_queue_ref_unlocked</literal> is deprecated and should not be used in newly-written code.</para></warning>
<para>
Increases the reference count of the asynchronous <parameter>queue</parameter> by 1.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-unref-and-unlock"/>g_async_queue_unref_and_unlock ()</title>
<indexterm role="deprecated"><primary>g_async_queue_unref_and_unlock</primary></indexterm><programlisting><link linkend="void">void</link>        g_async_queue_unref_and_unlock  (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<warning><para><literal>g_async_queue_unref_and_unlock</literal> is deprecated and should not be used in newly-written code.</para></warning>
<para>
Decreases the reference count of the asynchronous <parameter>queue</parameter> by 1 and
releases the lock. This function must be called while holding the
<parameter>queue</parameter>'s lock. If the reference count went to 0, the <parameter>queue</parameter> will be
destroyed and the memory allocated will be freed.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-push-unlocked"/>g_async_queue_push_unlocked ()</title>
<indexterm><primary>g_async_queue_push_unlocked</primary></indexterm><programlisting><link linkend="void">void</link>        g_async_queue_push_unlocked     (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue,
                                             <link linkend="gpointer">gpointer</link> data);</programlisting>
<para>
Pushes the <parameter>data</parameter> into the <parameter>queue</parameter>. <parameter>data</parameter> must not be <literal>NULL</literal>. This
function must be called while holding the <parameter>queue</parameter>'s lock.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>data</parameter>&nbsp;:</term>
<listitem><simpara> <parameter>data</parameter> to push into the <parameter>queue</parameter>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-pop-unlocked"/>g_async_queue_pop_unlocked ()</title>
<indexterm><primary>g_async_queue_pop_unlocked</primary></indexterm><programlisting><link linkend="gpointer">gpointer</link>    g_async_queue_pop_unlocked      (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Pops data from the <parameter>queue</parameter>. This function blocks until data become
available. This function must be called while holding the <parameter>queue</parameter>'s
lock.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> data from the queue.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-try-pop-unlocked"/>g_async_queue_try_pop_unlocked ()</title>
<indexterm><primary>g_async_queue_try_pop_unlocked</primary></indexterm><programlisting><link linkend="gpointer">gpointer</link>    g_async_queue_try_pop_unlocked  (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Tries to pop data from the <parameter>queue</parameter>. If no data is available, <literal>NULL</literal> is
returned. This function must be called while holding the <parameter>queue</parameter>'s
lock.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> data from the queue or <literal>NULL</literal>, when no data is
available immediately.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-timed-pop-unlocked"/>g_async_queue_timed_pop_unlocked ()</title>
<indexterm><primary>g_async_queue_timed_pop_unlocked</primary></indexterm><programlisting><link linkend="gpointer">gpointer</link>    g_async_queue_timed_pop_unlocked
                                            (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue,
                                             <link linkend="GTimeVal">GTimeVal</link> *end_time);</programlisting>
<para>
Pops data from the <parameter>queue</parameter>. If no data is received before <parameter>end_time</parameter>,
<literal>NULL</literal> is returned. This function must be called while holding the
<parameter>queue</parameter>'s lock.
</para>
<para>
To easily calculate <parameter>end_time</parameter> a combination of <link linkend="g-get-current-time"><function>g_get_current_time()</function></link>
and <link linkend="g-time-val-add"><function>g_time_val_add()</function></link> can be used.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>end_time</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GTimeVal"><type>GTimeVal</type></link>, determining the final time.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> data from the queue or <literal>NULL</literal>, when no data is
received before <parameter>end_time</parameter>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2>
<title><anchor id="g-async-queue-length-unlocked"/>g_async_queue_length_unlocked ()</title>
<indexterm><primary>g_async_queue_length_unlocked</primary></indexterm><programlisting><link linkend="gint">gint</link>        g_async_queue_length_unlocked   (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting>
<para>
Returns the length of the queue, negative values mean waiting
threads, positive values mean available entries in the
<parameter>queue</parameter>. Actually this function returns the number of data items in
the queue minus the number of waiting threads. Thus a return value
of 0 could mean 'n' entries in the queue and 'n' thread waiting.
That can happen due to locking of the queue or due to
scheduling. This function must be called while holding the <parameter>queue</parameter>'s
lock.</para>
<variablelist role="params">
<varlistentry><term><parameter>queue</parameter>&nbsp;:</term>
<listitem><simpara> a <link linkend="GAsyncQueue"><type>GAsyncQueue</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the length of the <parameter>queue</parameter>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>

</refsect1>




</refentry>