Home | History | Annotate | Download | only in gio
      1 /* GIO - GLib Input, Output and Streaming Library
      2  *
      3  * Copyright (C) 2006-2007 Red Hat, Inc.
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Lesser General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Lesser General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Lesser General
     16  * Public License along with this library; if not, write to the
     17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
     18  * Boston, MA 02111-1307, USA.
     19  *
     20  * Author: Alexander Larsson <alexl (at) redhat.com>
     21  */
     22 
     23 #include "config.h"
     24 
     25 #include <sys/types.h>
     26 #include <sys/stat.h>
     27 #include <string.h>
     28 #include <errno.h>
     29 #include <fcntl.h>
     30 #ifdef HAVE_UNISTD_H
     31 #include <unistd.h>
     32 #endif
     33 
     34 #include "gsimpleasyncresult.h"
     35 #include "gasyncresult.h"
     36 #include "gcancellable.h"
     37 #include "gioscheduler.h"
     38 #include <gio/gioerror.h>
     39 #include "glibintl.h"
     40 
     41 #include "gioalias.h"
     42 
     43 /**
     44  * SECTION:gsimpleasyncresult
     45  * @short_description: Simple asynchronous results implementation
     46  * @include: gio/gio.h
     47  * @see_also: #GAsyncResult
     48  *
     49  * Implements #GAsyncResult for simple cases. Most of the time, this
     50  * will be all an application needs, and will be used transparently.
     51  * Because of this, #GSimpleAsyncResult is used throughout GIO for
     52  * handling asynchronous functions.
     53  *
     54  * GSimpleAsyncResult handles #GAsyncReadyCallback<!-- -->s, error
     55  * reporting, operation cancellation and the final state of an operation,
     56  * completely transparent to the application. Results can be returned
     57  * as a pointer e.g. for functions that return data that is collected
     58  * asynchronously, a boolean value for checking the success or failure
     59  * of an operation, or a #gssize for operations which return the number
     60  * of bytes modified by the operation; all of the simple return cases
     61  * are covered.
     62  *
     63  * Most of the time, an application will not need to know of the details
     64  * of this API; it is handled transparently, and any necessary operations
     65  * are handled by #GAsyncResult's interface. However, if implementing a
     66  * new GIO module, for writing language bindings, or for complex
     67  * applications that need better control of how asynchronous operations
     68  * are completed, it is important to understand this functionality.
     69  *
     70  * GSimpleAsyncResults are tagged with the calling function to ensure
     71  * that asynchronous functions and their finishing functions are used
     72  * together correctly.
     73  *
     74  * To create a new #GSimpleAsyncResult, call g_simple_async_result_new().
     75  * If the result needs to be created for a #GError, use
     76  * g_simple_async_result_new_from_error(). If a #GError is not available
     77  * (e.g. the asynchronous operation's doesn't take a #GError argument),
     78  * but the result still needs to be created for an error condition, use
     79  * g_simple_async_result_new_error() (or g_simple_async_result_set_error_va()
     80  * if your application or binding requires passing a variable argument list
     81  * directly), and the error can then be propegated through the use of
     82  * g_simple_async_result_propagate_error().
     83  *
     84  * An asynchronous operation can be made to ignore a cancellation event by
     85  * calling g_simple_async_result_set_handle_cancellation() with a
     86  * #GSimpleAsyncResult for the operation and %FALSE. This is useful for
     87  * operations that are dangerous to cancel, such as close (which would
     88  * cause a leak if cancelled before being run).
     89  *
     90  * GSimpleAsyncResult can integrate into GLib's event loop, #GMainLoop,
     91  * or it can use #GThread<!-- -->s if available.
     92  * g_simple_async_result_complete() will finish an I/O task directly within
     93  * the main event loop. g_simple_async_result_complete_in_idle() will
     94  * integrate the I/O task into the main event loop as an idle function and
     95  * g_simple_async_result_run_in_thread() will run the job in a separate
     96  * thread.
     97  *
     98  * To set the results of an asynchronous function,
     99  * g_simple_async_result_set_op_res_gpointer(),
    100  * g_simple_async_result_set_op_res_gboolean(), and
    101  * g_simple_async_result_set_op_res_gssize()
    102  * are provided, setting the operation's result to a gpointer, gboolean, or
    103  * gssize, respectively.
    104  *
    105  * Likewise, to get the result of an asynchronous function,
    106  * g_simple_async_result_get_op_res_gpointer(),
    107  * g_simple_async_result_get_op_res_gboolean(), and
    108  * g_simple_async_result_get_op_res_gssize() are
    109  * provided, getting the operation's result as a gpointer, gboolean, and
    110  * gssize, respectively.
    111  **/
    112 
    113 static void g_simple_async_result_async_result_iface_init (GAsyncResultIface       *iface);
    114 
    115 struct _GSimpleAsyncResult
    116 {
    117   GObject parent_instance;
    118 
    119   GObject *source_object;
    120   GAsyncReadyCallback callback;
    121   gpointer user_data;
    122   GError *error;
    123   gboolean failed;
    124   gboolean handle_cancellation;
    125 
    126   gpointer source_tag;
    127 
    128   union {
    129     gpointer v_pointer;
    130     gboolean v_boolean;
    131     gssize   v_ssize;
    132   } op_res;
    133 
    134   GDestroyNotify destroy_op_res;
    135 };
    136 
    137 struct _GSimpleAsyncResultClass
    138 {
    139   GObjectClass parent_class;
    140 };
    141 
    142 
    143 G_DEFINE_TYPE_WITH_CODE (GSimpleAsyncResult, g_simple_async_result, G_TYPE_OBJECT,
    144 			 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT,
    145 						g_simple_async_result_async_result_iface_init))
    146 
    147 static void
    148 g_simple_async_result_finalize (GObject *object)
    149 {
    150   GSimpleAsyncResult *simple;
    151 
    152   simple = G_SIMPLE_ASYNC_RESULT (object);
    153 
    154   if (simple->source_object)
    155     g_object_unref (simple->source_object);
    156 
    157   if (simple->destroy_op_res)
    158     simple->destroy_op_res (simple->op_res.v_pointer);
    159 
    160   if (simple->error)
    161     g_error_free (simple->error);
    162 
    163   G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize (object);
    164 }
    165 
    166 static void
    167 g_simple_async_result_class_init (GSimpleAsyncResultClass *klass)
    168 {
    169   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
    170 
    171   gobject_class->finalize = g_simple_async_result_finalize;
    172 }
    173 
    174 static void
    175 g_simple_async_result_init (GSimpleAsyncResult *simple)
    176 {
    177   simple->handle_cancellation = TRUE;
    178 }
    179 
    180 /**
    181  * g_simple_async_result_new:
    182  * @source_object: a #GObject the asynchronous function was called with,
    183  * or %NULL.
    184  * @callback: a #GAsyncReadyCallback.
    185  * @user_data: user data passed to @callback.
    186  * @source_tag: the asynchronous function.
    187  *
    188  * Creates a #GSimpleAsyncResult.
    189  *
    190  * Returns: a #GSimpleAsyncResult.
    191  **/
    192 GSimpleAsyncResult *
    193 g_simple_async_result_new (GObject             *source_object,
    194                            GAsyncReadyCallback  callback,
    195                            gpointer             user_data,
    196                            gpointer             source_tag)
    197 {
    198   GSimpleAsyncResult *simple;
    199 
    200   g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
    201 
    202   simple = g_object_new (G_TYPE_SIMPLE_ASYNC_RESULT, NULL);
    203   simple->callback = callback;
    204   if (source_object)
    205     simple->source_object = g_object_ref (source_object);
    206   else
    207     simple->source_object = NULL;
    208   simple->user_data = user_data;
    209   simple->source_tag = source_tag;
    210 
    211   return simple;
    212 }
    213 
    214 /**
    215  * g_simple_async_result_new_from_error:
    216  * @source_object: a #GObject, or %NULL.
    217  * @callback: a #GAsyncReadyCallback.
    218  * @user_data: user data passed to @callback.
    219  * @error: a #GError location.
    220  *
    221  * Creates a #GSimpleAsyncResult from an error condition.
    222  *
    223  * Returns: a #GSimpleAsyncResult.
    224  **/
    225 GSimpleAsyncResult *
    226 g_simple_async_result_new_from_error (GObject             *source_object,
    227                                       GAsyncReadyCallback  callback,
    228                                       gpointer             user_data,
    229                                       GError              *error)
    230 {
    231   GSimpleAsyncResult *simple;
    232 
    233   g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
    234 
    235   simple = g_simple_async_result_new (source_object,
    236 				      callback,
    237 				      user_data, NULL);
    238   g_simple_async_result_set_from_error (simple, error);
    239 
    240   return simple;
    241 }
    242 
    243 /**
    244  * g_simple_async_result_new_error:
    245  * @source_object: a #GObject, or %NULL.
    246  * @callback: a #GAsyncReadyCallback.
    247  * @user_data: user data passed to @callback.
    248  * @domain: a #GQuark.
    249  * @code: an error code.
    250  * @format: a string with format characters.
    251  * @...: a list of values to insert into @format.
    252  *
    253  * Creates a new #GSimpleAsyncResult with a set error.
    254  *
    255  * Returns: a #GSimpleAsyncResult.
    256  **/
    257 GSimpleAsyncResult *
    258 g_simple_async_result_new_error (GObject             *source_object,
    259                                  GAsyncReadyCallback  callback,
    260                                  gpointer             user_data,
    261                                  GQuark               domain,
    262                                  gint                 code,
    263                                  const char          *format,
    264                                  ...)
    265 {
    266   GSimpleAsyncResult *simple;
    267   va_list args;
    268 
    269   g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
    270   g_return_val_if_fail (domain != 0, NULL);
    271   g_return_val_if_fail (format != NULL, NULL);
    272 
    273   simple = g_simple_async_result_new (source_object,
    274 				      callback,
    275 				      user_data, NULL);
    276 
    277   va_start (args, format);
    278   g_simple_async_result_set_error_va (simple, domain, code, format, args);
    279   va_end (args);
    280 
    281   return simple;
    282 }
    283 
    284 
    285 static gpointer
    286 g_simple_async_result_get_user_data (GAsyncResult *res)
    287 {
    288   return G_SIMPLE_ASYNC_RESULT (res)->user_data;
    289 }
    290 
    291 static GObject *
    292 g_simple_async_result_get_source_object (GAsyncResult *res)
    293 {
    294   if (G_SIMPLE_ASYNC_RESULT (res)->source_object)
    295     return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object);
    296   return NULL;
    297 }
    298 
    299 static void
    300 g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface)
    301 {
    302   iface->get_user_data = g_simple_async_result_get_user_data;
    303   iface->get_source_object = g_simple_async_result_get_source_object;
    304 }
    305 
    306 /**
    307  * g_simple_async_result_set_handle_cancellation:
    308  * @simple: a #GSimpleAsyncResult.
    309  * @handle_cancellation: a #gboolean.
    310  *
    311  * Sets whether to handle cancellation within the asynchronous operation.
    312  *
    313  **/
    314 void
    315 g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple,
    316                                                gboolean            handle_cancellation)
    317 {
    318   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    319   simple->handle_cancellation = handle_cancellation;
    320 }
    321 
    322 /**
    323  * g_simple_async_result_get_source_tag:
    324  * @simple: a #GSimpleAsyncResult.
    325  *
    326  * Gets the source tag for the #GSimpleAsyncResult.
    327  *
    328  * Returns: a #gpointer to the source object for the #GSimpleAsyncResult.
    329  **/
    330 gpointer
    331 g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple)
    332 {
    333   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
    334   return simple->source_tag;
    335 }
    336 
    337 /**
    338  * g_simple_async_result_propagate_error:
    339  * @simple: a #GSimpleAsyncResult.
    340  * @dest: a location to propegate the error to.
    341  *
    342  * Propagates an error from within the simple asynchronous result to
    343  * a given destination.
    344  *
    345  * Returns: %TRUE if the error was propegated to @dest. %FALSE otherwise.
    346  **/
    347 gboolean
    348 g_simple_async_result_propagate_error (GSimpleAsyncResult  *simple,
    349                                        GError             **dest)
    350 {
    351   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
    352 
    353   if (simple->failed)
    354     {
    355       g_propagate_error (dest, simple->error);
    356       simple->error = NULL;
    357       return TRUE;
    358     }
    359 
    360   return FALSE;
    361 }
    362 
    363 /**
    364  * g_simple_async_result_set_op_res_gpointer:
    365  * @simple: a #GSimpleAsyncResult.
    366  * @op_res: a pointer result from an asynchronous function.
    367  * @destroy_op_res: a #GDestroyNotify function.
    368  *
    369  * Sets the operation result within the asynchronous result to a pointer.
    370  **/
    371 void
    372 g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple,
    373                                            gpointer            op_res,
    374                                            GDestroyNotify      destroy_op_res)
    375 {
    376   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    377 
    378   simple->op_res.v_pointer = op_res;
    379   simple->destroy_op_res = destroy_op_res;
    380 }
    381 
    382 /**
    383  * g_simple_async_result_get_op_res_gpointer:
    384  * @simple: a #GSimpleAsyncResult.
    385  *
    386  * Gets a pointer result as returned by the asynchronous function.
    387  *
    388  * Returns: a pointer from the result.
    389  **/
    390 gpointer
    391 g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple)
    392 {
    393   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
    394   return simple->op_res.v_pointer;
    395 }
    396 
    397 /**
    398  * g_simple_async_result_set_op_res_gssize:
    399  * @simple: a #GSimpleAsyncResult.
    400  * @op_res: a #gssize.
    401  *
    402  * Sets the operation result within the asynchronous result to
    403  * the given @op_res.
    404  **/
    405 void
    406 g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple,
    407                                          gssize              op_res)
    408 {
    409   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    410   simple->op_res.v_ssize = op_res;
    411 }
    412 
    413 /**
    414  * g_simple_async_result_get_op_res_gssize:
    415  * @simple: a #GSimpleAsyncResult.
    416  *
    417  * Gets a gssize from the asynchronous result.
    418  *
    419  * Returns: a gssize returned from the asynchronous function.
    420  **/
    421 gssize
    422 g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple)
    423 {
    424   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0);
    425   return simple->op_res.v_ssize;
    426 }
    427 
    428 /**
    429  * g_simple_async_result_set_op_res_gboolean:
    430  * @simple: a #GSimpleAsyncResult.
    431  * @op_res: a #gboolean.
    432  *
    433  * Sets the operation result to a boolean within the asynchronous result.
    434  **/
    435 void
    436 g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple,
    437                                            gboolean            op_res)
    438 {
    439   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    440   simple->op_res.v_boolean = !!op_res;
    441 }
    442 
    443 /**
    444  * g_simple_async_result_get_op_res_gboolean:
    445  * @simple: a #GSimpleAsyncResult.
    446  *
    447  * Gets the operation result boolean from within the asynchronous result.
    448  *
    449  * Returns: %TRUE if the operation's result was %TRUE, %FALSE
    450  *     if the operation's result was %FALSE.
    451  **/
    452 gboolean
    453 g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple)
    454 {
    455   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
    456   return simple->op_res.v_boolean;
    457 }
    458 
    459 /**
    460  * g_simple_async_result_set_from_error:
    461  * @simple: a #GSimpleAsyncResult.
    462  * @error: #GError.
    463  *
    464  * Sets the result from a #GError.
    465  **/
    466 void
    467 g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
    468                                       GError             *error)
    469 {
    470   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    471   g_return_if_fail (error != NULL);
    472 
    473   if (simple->error)
    474     g_error_free (simple->error);
    475   simple->error = g_error_copy (error);
    476   simple->failed = TRUE;
    477 }
    478 
    479 static GError*
    480 _g_error_new_valist (GQuark     domain,
    481                     gint        code,
    482                     const char *format,
    483                     va_list     args)
    484 {
    485   GError *error;
    486   char *message;
    487 
    488   message = g_strdup_vprintf (format, args);
    489 
    490   error = g_error_new_literal (domain, code, message);
    491   g_free (message);
    492 
    493   return error;
    494 }
    495 
    496 /**
    497  * g_simple_async_result_set_error_va:
    498  * @simple: a #GSimpleAsyncResult.
    499  * @domain: a #GQuark (usually #G_IO_ERROR).
    500  * @code: an error code.
    501  * @format: a formatted error reporting string.
    502  * @args: va_list of arguments.
    503  *
    504  * Sets an error within the asynchronous result without a #GError.
    505  * Unless writing a binding, see g_simple_async_result_set_error().
    506  **/
    507 void
    508 g_simple_async_result_set_error_va (GSimpleAsyncResult *simple,
    509                                     GQuark              domain,
    510                                     gint                code,
    511                                     const char         *format,
    512                                     va_list             args)
    513 {
    514   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    515   g_return_if_fail (domain != 0);
    516   g_return_if_fail (format != NULL);
    517 
    518   if (simple->error)
    519     g_error_free (simple->error);
    520   simple->error = _g_error_new_valist (domain, code, format, args);
    521   simple->failed = TRUE;
    522 }
    523 
    524 /**
    525  * g_simple_async_result_set_error:
    526  * @simple: a #GSimpleAsyncResult.
    527  * @domain: a #GQuark (usually #G_IO_ERROR).
    528  * @code: an error code.
    529  * @format: a formatted error reporting string.
    530  * @...: a list of variables to fill in @format.
    531  *
    532  * Sets an error within the asynchronous result without a #GError.
    533  **/
    534 void
    535 g_simple_async_result_set_error (GSimpleAsyncResult *simple,
    536                                  GQuark              domain,
    537                                  gint                code,
    538                                  const char         *format,
    539                                  ...)
    540 {
    541   va_list args;
    542 
    543   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    544   g_return_if_fail (domain != 0);
    545   g_return_if_fail (format != NULL);
    546 
    547   va_start (args, format);
    548   g_simple_async_result_set_error_va (simple, domain, code, format, args);
    549   va_end (args);
    550 }
    551 
    552 /**
    553  * g_simple_async_result_complete:
    554  * @simple: a #GSimpleAsyncResult.
    555  *
    556  * Completes an asynchronous I/O job.
    557  * Must be called in the main thread, as it invokes the callback that
    558  * should be called in the main thread. If you are in a different thread
    559  * use g_simple_async_result_complete_in_idle().
    560  **/
    561 void
    562 g_simple_async_result_complete (GSimpleAsyncResult *simple)
    563 {
    564   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    565 
    566   if (simple->callback)
    567     simple->callback (simple->source_object,
    568 		      G_ASYNC_RESULT (simple),
    569 		      simple->user_data);
    570 }
    571 
    572 static gboolean
    573 complete_in_idle_cb (gpointer data)
    574 {
    575   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data);
    576 
    577   g_simple_async_result_complete (simple);
    578 
    579   return FALSE;
    580 }
    581 
    582 /**
    583  * g_simple_async_result_complete_in_idle:
    584  * @simple: a #GSimpleAsyncResult.
    585  *
    586  * Completes an asynchronous function in the main event loop using
    587  * an idle function.
    588  **/
    589 void
    590 g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
    591 {
    592   GSource *source;
    593   guint id;
    594 
    595   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    596 
    597   g_object_ref (simple);
    598 
    599   source = g_idle_source_new ();
    600   g_source_set_priority (source, G_PRIORITY_DEFAULT);
    601   g_source_set_callback (source, complete_in_idle_cb, simple, g_object_unref);
    602 
    603   id = g_source_attach (source, NULL);
    604   g_source_unref (source);
    605 }
    606 
    607 typedef struct {
    608   GSimpleAsyncResult *simple;
    609   GCancellable *cancellable;
    610   GSimpleAsyncThreadFunc func;
    611 } RunInThreadData;
    612 
    613 
    614 static gboolean
    615 complete_in_idle_cb_for_thread (gpointer _data)
    616 {
    617   RunInThreadData *data = _data;
    618   GSimpleAsyncResult *simple;
    619 
    620   simple = data->simple;
    621 
    622   if (simple->handle_cancellation &&
    623       g_cancellable_is_cancelled (data->cancellable))
    624     g_simple_async_result_set_error (simple,
    625                                      G_IO_ERROR,
    626                                      G_IO_ERROR_CANCELLED,
    627                                      "%s", _("Operation was cancelled"));
    628 
    629   g_simple_async_result_complete (simple);
    630 
    631   if (data->cancellable)
    632     g_object_unref (data->cancellable);
    633   g_object_unref (data->simple);
    634   g_free (data);
    635 
    636   return FALSE;
    637 }
    638 
    639 static gboolean
    640 run_in_thread (GIOSchedulerJob *job,
    641                GCancellable    *c,
    642                gpointer         _data)
    643 {
    644   RunInThreadData *data = _data;
    645   GSimpleAsyncResult *simple = data->simple;
    646   GSource *source;
    647   guint id;
    648 
    649   if (simple->handle_cancellation &&
    650       g_cancellable_is_cancelled (c))
    651     g_simple_async_result_set_error (simple,
    652                                      G_IO_ERROR,
    653                                      G_IO_ERROR_CANCELLED,
    654                                      "%s", _("Operation was cancelled"));
    655   else
    656     data->func (simple,
    657                 simple->source_object,
    658                 c);
    659 
    660   source = g_idle_source_new ();
    661   g_source_set_priority (source, G_PRIORITY_DEFAULT);
    662   g_source_set_callback (source, complete_in_idle_cb_for_thread, data, NULL);
    663 
    664   id = g_source_attach (source, NULL);
    665   g_source_unref (source);
    666 
    667   return FALSE;
    668 }
    669 
    670 /**
    671  * g_simple_async_result_run_in_thread:
    672  * @simple: a #GSimpleAsyncResult.
    673  * @func: a #GSimpleAsyncThreadFunc.
    674  * @io_priority: the io priority of the request.
    675  * @cancellable: optional #GCancellable object, %NULL to ignore.
    676  *
    677  * Runs the asynchronous job in a separated thread.
    678  **/
    679 void
    680 g_simple_async_result_run_in_thread (GSimpleAsyncResult     *simple,
    681                                      GSimpleAsyncThreadFunc  func,
    682                                      int                     io_priority,
    683                                      GCancellable           *cancellable)
    684 {
    685   RunInThreadData *data;
    686 
    687   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
    688   g_return_if_fail (func != NULL);
    689 
    690   data = g_new (RunInThreadData, 1);
    691   data->func = func;
    692   data->simple = g_object_ref (simple);
    693   data->cancellable = cancellable;
    694   if (cancellable)
    695     g_object_ref (cancellable);
    696   g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
    697 }
    698 
    699 /**
    700  * g_simple_async_result_is_valid:
    701  * @result: the #GAsyncResult passed to the _finish function.
    702  * @source: the #GObject passed to the _finish function.
    703  * @source_tag: the asynchronous function.
    704  *
    705  * Ensures that the data passed to the _finish function of an async
    706  * operation is consistent.  Three checks are performed.
    707  *
    708  * First, @result is checked to ensure that it is really a
    709  * #GSimpleAsyncResult.  Second, @source is checked to ensure that it
    710  * matches the source object of @result.  Third, @source_tag is
    711  * checked to ensure that it is equal to the source_tag argument given
    712  * to g_simple_async_result_new() (which, by convention, is a pointer
    713  * to the _async function corresponding to the _finish function from
    714  * which this function is called).
    715  *
    716  * Returns: #TRUE if all checks passed or #FALSE if any failed.
    717  **/
    718 gboolean
    719 g_simple_async_result_is_valid (GAsyncResult *result,
    720                                 GObject      *source,
    721                                 gpointer      source_tag)
    722 {
    723   GSimpleAsyncResult *simple;
    724   GObject *cmp_source;
    725 
    726   if (!G_IS_SIMPLE_ASYNC_RESULT (result))
    727     return FALSE;
    728   simple = (GSimpleAsyncResult *)result;
    729 
    730   cmp_source = g_async_result_get_source_object (result);
    731   if (cmp_source != source)
    732     {
    733       g_object_unref (cmp_source);
    734       return FALSE;
    735     }
    736   g_object_unref (cmp_source);
    737 
    738   return source_tag == g_simple_async_result_get_source_tag (simple);
    739 }
    740 
    741 /**
    742  * g_simple_async_report_error_in_idle:
    743  * @object: a #GObject.
    744  * @callback: a #GAsyncReadyCallback.
    745  * @user_data: user data passed to @callback.
    746  * @domain: a #GQuark containing the error domain (usually #G_IO_ERROR).
    747  * @code: a specific error code.
    748  * @format: a formatted error reporting string.
    749  * @...: a list of variables to fill in @format.
    750  *
    751  * Reports an error in an asynchronous function in an idle function by
    752  * directly setting the contents of the #GAsyncResult with the given error
    753  * information.
    754  **/
    755 void
    756 g_simple_async_report_error_in_idle (GObject             *object,
    757                                      GAsyncReadyCallback  callback,
    758                                      gpointer             user_data,
    759                                      GQuark               domain,
    760                                      gint                 code,
    761                                      const char          *format,
    762                                      ...)
    763 {
    764   GSimpleAsyncResult *simple;
    765   va_list args;
    766 
    767   g_return_if_fail (G_IS_OBJECT (object));
    768   g_return_if_fail (domain != 0);
    769   g_return_if_fail (format != NULL);
    770 
    771   simple = g_simple_async_result_new (object,
    772 				      callback,
    773 				      user_data, NULL);
    774 
    775   va_start (args, format);
    776   g_simple_async_result_set_error_va (simple, domain, code, format, args);
    777   va_end (args);
    778   g_simple_async_result_complete_in_idle (simple);
    779   g_object_unref (simple);
    780 }
    781 
    782 /**
    783  * g_simple_async_report_gerror_in_idle:
    784  * @object: a #GObject.
    785  * @callback: a #GAsyncReadyCallback.
    786  * @user_data: user data passed to @callback.
    787  * @error: the #GError to report
    788  *
    789  * Reports an error in an idle function. Similar to
    790  * g_simple_async_report_error_in_idle(), but takes a #GError rather
    791  * than building a new one.
    792  **/
    793 void
    794 g_simple_async_report_gerror_in_idle (GObject *object,
    795 				      GAsyncReadyCallback callback,
    796 				      gpointer user_data,
    797 				      GError *error)
    798 {
    799   GSimpleAsyncResult *simple;
    800 
    801   g_return_if_fail (G_IS_OBJECT (object));
    802   g_return_if_fail (error != NULL);
    803 
    804   simple = g_simple_async_result_new_from_error (object,
    805 						 callback,
    806 						 user_data,
    807 						 error);
    808   g_simple_async_result_complete_in_idle (simple);
    809   g_object_unref (simple);
    810 }
    811 
    812 #define __G_SIMPLE_ASYNC_RESULT_C__
    813 #include "gioaliasdef.c"
    814