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