<?xml version="1.0"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
]>
<refentry id="GCancellable">
<refmeta>
<refentrytitle role="top_of_page" id="GCancellable.top_of_page">GCancellable</refentrytitle>
<manvolnum>3</manvolnum>
<refmiscinfo>GIO Library</refmiscinfo>
</refmeta>

<refnamediv>
<refname>GCancellable</refname>
<refpurpose>Thread-safe Operation Cancellation Stack</refpurpose>
</refnamediv>

<refsynopsisdiv id="GCancellable.synopsis" role="synopsis">
<title role="synopsis.title">Synopsis</title>

<synopsis>

#include &lt;gio/gio.h&gt;

                    <link linkend="GCancellable-struct">GCancellable</link>;
<link linkend="GCancellable">GCancellable</link> *      <link linkend="g-cancellable-new">g_cancellable_new</link>                   (void);
<link linkend="gboolean">gboolean</link>            <link linkend="g-cancellable-is-cancelled">g_cancellable_is_cancelled</link>          (<link linkend="GCancellable">GCancellable</link> *cancellable);
<link linkend="gboolean">gboolean</link>            <link linkend="g-cancellable-set-error-if-cancelled">g_cancellable_set_error_if_cancelled</link>
                                                        (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                         <link linkend="GError">GError</link> **error);
<link linkend="int">int</link>                 <link linkend="g-cancellable-get-fd">g_cancellable_get_fd</link>                (<link linkend="GCancellable">GCancellable</link> *cancellable);
<link linkend="void">void</link>                <link linkend="g-cancellable-make-pollfd">g_cancellable_make_pollfd</link>           (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                         <link linkend="GPollFD">GPollFD</link> *pollfd);
<link linkend="GCancellable">GCancellable</link> *      <link linkend="g-cancellable-get-current">g_cancellable_get_current</link>           (void);
<link linkend="void">void</link>                <link linkend="g-cancellable-pop-current">g_cancellable_pop_current</link>           (<link linkend="GCancellable">GCancellable</link> *cancellable);
<link linkend="void">void</link>                <link linkend="g-cancellable-push-current">g_cancellable_push_current</link>          (<link linkend="GCancellable">GCancellable</link> *cancellable);
<link linkend="void">void</link>                <link linkend="g-cancellable-reset">g_cancellable_reset</link>                 (<link linkend="GCancellable">GCancellable</link> *cancellable);
<link linkend="gulong">gulong</link>              <link linkend="g-cancellable-connect">g_cancellable_connect</link>               (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                         <link linkend="GCallback">GCallback</link> callback,
                                                         <link linkend="gpointer">gpointer</link> data,
                                                         <link linkend="GDestroyNotify">GDestroyNotify</link> data_destroy_func);
<link linkend="void">void</link>                <link linkend="g-cancellable-disconnect">g_cancellable_disconnect</link>            (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                         <link linkend="gulong">gulong</link> handler_id);
<link linkend="void">void</link>                <link linkend="g-cancellable-cancel">g_cancellable_cancel</link>                (<link linkend="GCancellable">GCancellable</link> *cancellable);
</synopsis>
</refsynopsisdiv>

<refsect1 id="GCancellable.object-hierarchy" role="object_hierarchy">
<title role="object_hierarchy.title">Object Hierarchy</title>
<synopsis>
  <link linkend="GObject">GObject</link>
   +----GCancellable
</synopsis>
</refsect1>






<refsect1 id="GCancellable.signals" role="signal_proto">
<title role="signal_proto.title">Signals</title>
<synopsis>
  &quot;<link linkend="GCancellable-cancelled">cancelled</link>&quot;                                      : Run Last
</synopsis>
</refsect1>


<refsect1 id="GCancellable.description" role="desc">
<title role="desc.title">Description</title>
<para>
GCancellable is a thread-safe operation cancellation stack used 
throughout GIO to allow for cancellation of synchronous and
asynchronous operations.</para>
<para>
</para>
</refsect1>

<refsect1 id="GCancellable.details" role="details">
<title role="details.title">Details</title>
<refsect2 id="GCancellable-struct" role="struct">
<title>GCancellable</title>
<indexterm zone="GCancellable-struct"><primary sortas="Cancellable">GCancellable</primary></indexterm><programlisting>typedef struct _GCancellable GCancellable;</programlisting>
<para>
Allows actions to be cancelled.</para>
<para>
</para></refsect2>
<refsect2 id="g-cancellable-new" role="function">
<title>g_cancellable_new ()</title>
<indexterm zone="g-cancellable-new"><primary sortas="cancellable_new">g_cancellable_new</primary></indexterm><programlisting><link linkend="GCancellable">GCancellable</link> *      g_cancellable_new                   (void);</programlisting>
<para>
Creates a new <link linkend="GCancellable"><type>GCancellable</type></link> object.
</para>
<para>
Applications that want to start one or more operations
that should be cancellable should create a <link linkend="GCancellable"><type>GCancellable</type></link>
and pass it to the operations.
</para>
<para>
One <link linkend="GCancellable"><type>GCancellable</type></link> can be used in multiple consecutive
operations, but not in multiple concurrent operations.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><emphasis>Returns</emphasis>&#160;:</term><listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link>.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-is-cancelled" role="function">
<title>g_cancellable_is_cancelled ()</title>
<indexterm zone="g-cancellable-is-cancelled"><primary sortas="cancellable_is_cancelled">g_cancellable_is_cancelled</primary></indexterm><programlisting><link linkend="gboolean">gboolean</link>            g_cancellable_is_cancelled          (<link linkend="GCancellable">GCancellable</link> *cancellable);</programlisting>
<para>
Checks if a cancellable job has been cancelled.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link> or NULL.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis>&#160;:</term><listitem><simpara> <link linkend="TRUE--CAPS"><literal>TRUE</literal></link> if <parameter>cancellable</parameter> is cancelled, 
FALSE if called with <link linkend="NULL--CAPS"><literal>NULL</literal></link> or if item is not cancelled. 
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-set-error-if-cancelled" role="function">
<title>g_cancellable_set_error_if_cancelled ()</title>
<indexterm zone="g-cancellable-set-error-if-cancelled"><primary sortas="cancellable_set_error_if_cancelled">g_cancellable_set_error_if_cancelled</primary></indexterm><programlisting><link linkend="gboolean">gboolean</link>            g_cancellable_set_error_if_cancelled
                                                        (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                         <link linkend="GError">GError</link> **error);</programlisting>
<para>
If the <parameter>cancellable</parameter> is cancelled, sets the error to notify
that the operation was cancelled.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link> object.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>error</parameter>&#160;:</term>
<listitem><simpara> <link linkend="GError"><type>GError</type></link> to append error state to.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis>&#160;:</term><listitem><simpara> <link linkend="TRUE--CAPS"><literal>TRUE</literal></link> if <parameter>cancellable</parameter> was cancelled, <link linkend="FALSE--CAPS"><literal>FALSE</literal></link> if it was not.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-get-fd" role="function">
<title>g_cancellable_get_fd ()</title>
<indexterm zone="g-cancellable-get-fd"><primary sortas="cancellable_get_fd">g_cancellable_get_fd</primary></indexterm><programlisting><link linkend="int">int</link>                 g_cancellable_get_fd                (<link linkend="GCancellable">GCancellable</link> *cancellable);</programlisting>
<para>
Gets the file descriptor for a cancellable job. This can be used to
implement cancellable operations on Unix systems. The returned fd will
turn readable when <parameter>cancellable</parameter> is cancelled.
</para>
<para>
You are not supposed to read from the fd yourself, just check for
readable status. Reading to unset the readable status is done
with <link linkend="g-cancellable-reset"><function>g_cancellable_reset()</function></link>.
</para>
<para>
See also <link linkend="g-cancellable-make-pollfd"><function>g_cancellable_make_pollfd()</function></link>.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis>&#160;:</term><listitem><simpara> A valid file descriptor. <link linkend="1--CAPS"><literal>-1</literal></link> if the file descriptor 
is not supported, or on errors. 
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-make-pollfd" role="function">
<title>g_cancellable_make_pollfd ()</title>
<indexterm zone="g-cancellable-make-pollfd"><primary sortas="cancellable_make_pollfd">g_cancellable_make_pollfd</primary></indexterm><programlisting><link linkend="void">void</link>                g_cancellable_make_pollfd           (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                         <link linkend="GPollFD">GPollFD</link> *pollfd);</programlisting>
<para>
Creates a <link linkend="GPollFD"><type>GPollFD</type></link> corresponding to <parameter>cancellable</parameter>; this can be passed
to <link linkend="g-poll"><function>g_poll()</function></link> and used to poll for cancellation. This is useful both
for unix systems without a native poll and for portability to
windows.
</para>
<para>
You are not supposed to read from the fd yourself, just check for
readable status. Reading to unset the readable status is done
with <link linkend="g-cancellable-reset"><function>g_cancellable_reset()</function></link>.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>pollfd</parameter>&#160;:</term>
<listitem><simpara> a pointer to a <link linkend="GPollFD"><type>GPollFD</type></link>
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-get-current" role="function">
<title>g_cancellable_get_current ()</title>
<indexterm zone="g-cancellable-get-current"><primary sortas="cancellable_get_current">g_cancellable_get_current</primary></indexterm><programlisting><link linkend="GCancellable">GCancellable</link> *      g_cancellable_get_current           (void);</programlisting>
<para>
Gets the top cancellable from the stack.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><emphasis>Returns</emphasis>&#160;:</term><listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link> from the top of the stack, or <link linkend="NULL--CAPS"><literal>NULL</literal></link>
if the stack is empty.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-pop-current" role="function">
<title>g_cancellable_pop_current ()</title>
<indexterm zone="g-cancellable-pop-current"><primary sortas="cancellable_pop_current">g_cancellable_pop_current</primary></indexterm><programlisting><link linkend="void">void</link>                g_cancellable_pop_current           (<link linkend="GCancellable">GCancellable</link> *cancellable);</programlisting>
<para>
Pops <parameter>cancellable</parameter> off the cancellable stack (verifying that <parameter>cancellable</parameter>
is on the top of the stack).</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link> object
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-push-current" role="function">
<title>g_cancellable_push_current ()</title>
<indexterm zone="g-cancellable-push-current"><primary sortas="cancellable_push_current">g_cancellable_push_current</primary></indexterm><programlisting><link linkend="void">void</link>                g_cancellable_push_current          (<link linkend="GCancellable">GCancellable</link> *cancellable);</programlisting>
<para>
Pushes <parameter>cancellable</parameter> onto the cancellable stack. The current
cancllable can then be recieved using <link linkend="g-cancellable-get-current"><function>g_cancellable_get_current()</function></link>.
</para>
<para>
This is useful when implementing cancellable operations in
code that does not allow you to pass down the cancellable object.
</para>
<para>
This is typically called automatically by e.g. <link linkend="GFile"><type>GFile</type></link> operations,
so you rarely have to call this yourself.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link> object
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-reset" role="function">
<title>g_cancellable_reset ()</title>
<indexterm zone="g-cancellable-reset"><primary sortas="cancellable_reset">g_cancellable_reset</primary></indexterm><programlisting><link linkend="void">void</link>                g_cancellable_reset                 (<link linkend="GCancellable">GCancellable</link> *cancellable);</programlisting>
<para>
Resets <parameter>cancellable</parameter> to its uncancelled state.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link> object.
</simpara></listitem></varlistentry>
</variablelist></refsect2>
<refsect2 id="g-cancellable-connect" role="function" condition="since:2.22">
<title>g_cancellable_connect ()</title>
<indexterm zone="g-cancellable-connect" role="2.22"><primary sortas="cancellable_connect">g_cancellable_connect</primary></indexterm><programlisting><link linkend="gulong">gulong</link>              g_cancellable_connect               (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                         <link linkend="GCallback">GCallback</link> callback,
                                                         <link linkend="gpointer">gpointer</link> data,
                                                         <link linkend="GDestroyNotify">GDestroyNotify</link> data_destroy_func);</programlisting>
<para>
Convenience function to connect to the <link linkend="GCancellable-cancelled"><type>"cancelled"</type></link>
signal. Also handles the race condition that may happen
if the cancellable is cancelled right before connecting.
</para>
<para>
<parameter>callback</parameter> is called at most once, either directly at the
time of the connect if <parameter>cancellable</parameter> is already cancelled,
or when <parameter>cancellable</parameter> is cancelled in some thread.
</para>
<para>
<parameter>data_destroy_func</parameter> will be called when the handler is
disconnected, or immediately if the cancellable is already
cancelled.
</para>
<para>
See <link linkend="GCancellable-cancelled"><type>"cancelled"</type></link> for details on how to use this.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> A <link linkend="GCancellable"><type>GCancellable</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>callback</parameter>&#160;:</term>
<listitem><simpara> The <link linkend="GCallback"><type>GCallback</type></link> to connect.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>data</parameter>&#160;:</term>
<listitem><simpara> Data to pass to <parameter>callback</parameter>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>data_destroy_func</parameter>&#160;:</term>
<listitem><simpara> Free function for <parameter>data</parameter> or <link linkend="NULL--CAPS"><literal>NULL</literal></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><emphasis>Returns</emphasis>&#160;:</term><listitem><simpara> The id of the signal handler or 0 if <parameter>cancellable</parameter> has already
         been cancelled.

</simpara></listitem></varlistentry>
</variablelist><para role="since">Since 2.22</para></refsect2>
<refsect2 id="g-cancellable-disconnect" role="function" condition="since:2.22">
<title>g_cancellable_disconnect ()</title>
<indexterm zone="g-cancellable-disconnect" role="2.22"><primary sortas="cancellable_disconnect">g_cancellable_disconnect</primary></indexterm><programlisting><link linkend="void">void</link>                g_cancellable_disconnect            (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                         <link linkend="gulong">gulong</link> handler_id);</programlisting>
<para>
Disconnects a handler from an cancellable instance similar to
<link linkend="g-signal-handler-disconnect"><function>g_signal_handler_disconnect()</function></link> but ensures that once this
function returns the handler will not run anymore in any thread.
</para>
<para>
This avoids a race condition where a thread cancels at the
same time as the cancellable operation is finished and the
signal handler is removed. See <link linkend="GCancellable-cancelled"><type>"cancelled"</type></link> for
details on how to use this.
</para>
<para>
If <parameter>cancellable</parameter> is <link linkend="NULL--CAPS"><literal>NULL</literal></link> or <parameter>handler_id</parameter> is <link linkend="0--CAPS"><literal>0</literal></link> this function does
nothing.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> A <link linkend="GCancellable"><type>GCancellable</type></link> or <link linkend="NULL--CAPS"><literal>NULL</literal></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>handler_id</parameter>&#160;:</term>
<listitem><simpara> Handler id of the handler to be disconnected, or <link linkend="0--CAPS"><literal>0</literal></link>.
</simpara></listitem></varlistentry>
</variablelist><para role="since">Since 2.22</para></refsect2>
<refsect2 id="g-cancellable-cancel" role="function">
<title>g_cancellable_cancel ()</title>
<indexterm zone="g-cancellable-cancel"><primary sortas="cancellable_cancel">g_cancellable_cancel</primary></indexterm><programlisting><link linkend="void">void</link>                g_cancellable_cancel                (<link linkend="GCancellable">GCancellable</link> *cancellable);</programlisting>
<para>
Will set <parameter>cancellable</parameter> to cancelled, and will emit the
<link linkend="GCancellable-cancelled"><type>"cancelled"</type></link> signal. (However, see the warning about
race conditions in the documentation for that signal if you are
planning to connect to it.)
</para>
<para>
This function is thread-safe. In other words, you can safely call
it from a thread other than the one running the operation that was
passed the <parameter>cancellable</parameter>.
</para>
<para>
The convention within gio is that cancelling an asynchronous
operation causes it to complete asynchronously. That is, if you
cancel the operation from the same thread in which it is running,
then the operation's <link linkend="GAsyncReadyCallback"><type>GAsyncReadyCallback</type></link> will not be invoked until
the application returns to the main loop.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link> object.
</simpara></listitem></varlistentry>
</variablelist></refsect2>

</refsect1>

<refsect1 id="GCancellable.signal-details" role="signals">
<title role="signals.title">Signal Details</title>
<refsect2 id="GCancellable-cancelled" role="signal"><title>The <literal>&quot;cancelled&quot;</literal> signal</title>
<indexterm zone="GCancellable-cancelled"><primary sortas="Cancellable::cancelled">GCancellable::cancelled</primary></indexterm><programlisting><link linkend="void">void</link>                user_function                      (<link linkend="GCancellable">GCancellable</link> *cancellable,
                                                        <link linkend="gpointer">gpointer</link>      user_data)        : Run Last</programlisting>
<para>
Emitted when the operation has been cancelled.
</para>
<para>
Can be used by implementations of cancellable operations. If the
operation is cancelled from another thread, the signal will be
emitted in the thread that cancelled the operation, not the
thread that is running the operation.
</para>
<para>
Note that disconnecting from this signal (or any signal) in a
multi-threaded program is prone to race conditions. For instance
it is possible that a signal handler may be invoked even
<emphasis>after</emphasis> a call to
<link linkend="g-signal-handler-disconnect"><function>g_signal_handler_disconnect()</function></link> for that handler has already
returned.
</para>
<para>
There is also a problem when cancellation happen
right before connecting to the signal. If this happens the
signal will unexpectedly not be emitted, and checking before
connecting to the signal leaves a race condition where this is
still happening.
</para>
<para>
In order to make it safe and easy to connect handlers there
are two helper functions: <link linkend="g-cancellable-connect"><function>g_cancellable_connect()</function></link> and
<link linkend="g-cancellable-disconnect"><function>g_cancellable_disconnect()</function></link> which protect against problems
like this.
</para>
<para>
An example of how to us this:
<informalexample><programlisting>
    /<!-- -->* Make sure we don't do any unnecessary work if already cancelled *<!-- -->/
    if (g_cancellable_set_error_if_cancelled (cancellable))
      return;
    /<!-- -->* Set up all the data needed to be able to
     * handle cancellation of the operation *<!-- -->/
    my_data = my_data_new (...);

    id = 0;
    if (cancellable)
      id = g_cancellable_connect (cancellable,
    			      G_CALLBACK (cancelled_handler)
    			      data, NULL);

    /<!-- -->* cancellable operation here... *<!-- -->/

    g_cancellable_disconnect (cancellable, id);

    /<!-- -->* cancelled_handler is never called after this, it
     * is now safe to free the data *<!-- -->/
    my_data_free (my_data);  
</programlisting></informalexample>
</para>
<para>
Note that the cancelled signal is emitted in the thread that
the user cancelled from, which may be the main thread. So, the
cancellable signal should not do something that can block.</para>
<para>
</para><variablelist role="params">
<varlistentry><term><parameter>cancellable</parameter>&#160;:</term>
<listitem><simpara> a <link linkend="GCancellable"><type>GCancellable</type></link>.
</simpara></listitem></varlistentry>
<varlistentry><term><parameter>user_data</parameter>&#160;:</term>
<listitem><simpara>user data set when the signal handler was connected.</simpara></listitem></varlistentry>
</variablelist></refsect2>
</refsect1>



</refentry>
