GSocketControlMessage: clean up confusing code
[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 "gasyncresult.h"
36 #include "gcancellable.h"
37 #include "gioscheduler.h"
38 #include <gio/gioerror.h>
39 #include "glibintl.h"
40
41
42 /**
43  * SECTION:gsimpleasyncresult
44  * @short_description: Simple asynchronous results implementation
45  * @include: gio/gio.h
46  * @see_also: #GAsyncResult
47  *
48  * Implements #GAsyncResult for simple cases. Most of the time, this
49  * will be all an application needs, and will be used transparently.
50  * Because of this, #GSimpleAsyncResult is used throughout GIO for
51  * handling asynchronous functions.
52  *
53  * GSimpleAsyncResult handles #GAsyncReadyCallback<!-- -->s, error
54  * reporting, operation cancellation and the final state of an operation,
55  * completely transparent to the application. Results can be returned
56  * as a pointer e.g. for functions that return data that is collected
57  * asynchronously, a boolean value for checking the success or failure
58  * of an operation, or a #gssize for operations which return the number
59  * of bytes modified by the operation; all of the simple return cases
60  * are covered.
61  *
62  * Most of the time, an application will not need to know of the details
63  * of this API; it is handled transparently, and any necessary operations
64  * are handled by #GAsyncResult's interface. However, if implementing a
65  * new GIO module, for writing language bindings, or for complex
66  * applications that need better control of how asynchronous operations
67  * are completed, it is important to understand this functionality.
68  *
69  * GSimpleAsyncResults are tagged with the calling function to ensure
70  * that asynchronous functions and their finishing functions are used
71  * together correctly.
72  *
73  * To create a new #GSimpleAsyncResult, call g_simple_async_result_new().
74  * If the result needs to be created for a #GError, use
75  * g_simple_async_result_new_from_error(). If a #GError is not available
76  * (e.g. the asynchronous operation's doesn't take a #GError argument),
77  * but the result still needs to be created for an error condition, use
78  * g_simple_async_result_new_error() (or g_simple_async_result_set_error_va()
79  * if your application or binding requires passing a variable argument list
80  * directly), and the error can then be propagated through the use of
81  * g_simple_async_result_propagate_error().
82  *
83  * An asynchronous operation can be made to ignore a cancellation event by
84  * calling g_simple_async_result_set_handle_cancellation() with a
85  * #GSimpleAsyncResult for the operation and %FALSE. This is useful for
86  * operations that are dangerous to cancel, such as close (which would
87  * cause a leak if cancelled before being run).
88  *
89  * GSimpleAsyncResult can integrate into GLib's event loop, #GMainLoop,
90  * or it can use #GThread<!-- -->s if available.
91  * g_simple_async_result_complete() will finish an I/O task directly
92  * from the point where it is called. g_simple_async_result_complete_in_idle()
93  * will finish it from an idle handler in the <link
94  * linkend="g-main-context-push-thread-default">thread-default main
95  * context</link>. g_simple_async_result_run_in_thread() will run the
96  * job in a separate thread and then deliver the result to the
97  * thread-default main context.
98  *
99  * To set the results of an asynchronous function,
100  * g_simple_async_result_set_op_res_gpointer(),
101  * g_simple_async_result_set_op_res_gboolean(), and
102  * g_simple_async_result_set_op_res_gssize()
103  * are provided, setting the operation's result to a gpointer, gboolean, or
104  * gssize, respectively.
105  *
106  * Likewise, to get the result of an asynchronous function,
107  * g_simple_async_result_get_op_res_gpointer(),
108  * g_simple_async_result_get_op_res_gboolean(), and
109  * g_simple_async_result_get_op_res_gssize() are
110  * provided, getting the operation's result as a gpointer, gboolean, and
111  * gssize, respectively.
112  *
113  * For the details of the requirements implementations must respect, see
114  * #GAsyncResult.  A typical implementation of an asynchronous operation
115  * using GSimpleAsyncResult looks something like this:
116  *
117  * |[
118  * static void
119  * baked_cb (Cake    *cake,
120  *           gpointer user_data)
121  * {
122  *   /&ast; In this example, this callback is not given a reference to the cake, so
123  *    &ast; the GSimpleAsyncResult has to take a reference to it.
124  *    &ast;/
125  *   GSimpleAsyncResult *result = user_data;
126  *
127  *   if (cake == NULL)
128  *     g_simple_async_result_set_error (result,
129  *                                      BAKER_ERRORS,
130  *                                      BAKER_ERROR_NO_FLOUR,
131  *                                      "Go to the supermarket");
132  *   else
133  *     g_simple_async_result_set_op_res_gpointer (result,
134  *                                                g_object_ref (cake),
135  *                                                g_object_unref);
136  *
137  *
138  *   /&ast; In this example, we assume that baked_cb is called as a callback from
139  *    &ast; the mainloop, so it's safe to complete the operation synchronously here.
140  *    &ast; If, however, _baker_prepare_cake () might call its callback without
141  *    &ast; first returning to the mainloop — inadvisable, but some APIs do so —
142  *    &ast; we would need to use g_simple_async_result_complete_in_idle().
143  *    &ast;/
144  *   g_simple_async_result_complete (result);
145  *   g_object_unref (result);
146  * }
147  *
148  * void
149  * baker_bake_cake_async (Baker              *self,
150  *                        guint               radius,
151  *                        GAsyncReadyCallback callback,
152  *                        gpointer            user_data)
153  * {
154  *   GSimpleAsyncResult *simple;
155  *   Cake               *cake;
156  *
157  *   if (radius < 3)
158  *     {
159  *       g_simple_async_report_error_in_idle (G_OBJECT (self),
160  *                                            callback,
161  *                                            user_data,
162  *                                            BAKER_ERRORS,
163  *                                            BAKER_ERROR_TOO_SMALL,
164  *                                            "%ucm radius cakes are silly",
165  *                                            radius);
166  *       return;
167  *     }
168  *
169  *   simple = g_simple_async_result_new (G_OBJECT (self),
170  *                                       callback,
171  *                                       user_data,
172  *                                       baker_bake_cake_async);
173  *   cake = _baker_get_cached_cake (self, radius);
174  *
175  *   if (cake != NULL)
176  *     {
177  *       g_simple_async_result_set_op_res_gpointer (simple,
178  *                                                  g_object_ref (cake),
179  *                                                  g_object_unref);
180  *       g_simple_async_result_complete_in_idle (simple);
181  *       g_object_unref (simple);
182  *       /&ast; Drop the reference returned by _baker_get_cached_cake(); the
183  *        &ast; GSimpleAsyncResult has taken its own reference.
184  *        &ast;/
185  *       g_object_unref (cake);
186  *       return;
187  *     }
188  *
189  *   _baker_prepare_cake (self, radius, baked_cb, user_data);
190  * }
191  *
192  * Cake *
193  * baker_bake_cake_finish (Baker        *self,
194  *                         GAsyncResult *result,
195  *                         GError      **error)
196  * {
197  *   GSimpleAsyncResult *simple;
198  *   Cake               *cake;
199  *
200  *   g_return_val_if_fail (g_simple_async_result_is_valid (result,
201  *                                                         G_OBJECT (self),
202  *                                                         baker_bake_cake_async),
203  *                         NULL);
204  *
205  *   simple = (GSimpleAsyncResult *) result;
206  *
207  *   if (g_simple_async_result_propagate_error (simple, error))
208  *     return NULL;
209  *
210  *   cake = CAKE (g_simple_async_result_get_op_res_gpointer (simple));
211  *   return g_object_ref (cake);
212  * }
213  * ]|
214  */
215
216 static void g_simple_async_result_async_result_iface_init (GAsyncResultIface       *iface);
217
218 struct _GSimpleAsyncResult
219 {
220   GObject parent_instance;
221
222   GObject *source_object;
223   GAsyncReadyCallback callback;
224   gpointer user_data;
225   GMainContext *context;
226   GError *error;
227   gboolean failed;
228   gboolean handle_cancellation;
229
230   gpointer source_tag;
231
232   union {
233     gpointer v_pointer;
234     gboolean v_boolean;
235     gssize   v_ssize;
236   } op_res;
237
238   GDestroyNotify destroy_op_res;
239 };
240
241 struct _GSimpleAsyncResultClass
242 {
243   GObjectClass parent_class;
244 };
245
246
247 G_DEFINE_TYPE_WITH_CODE (GSimpleAsyncResult, g_simple_async_result, G_TYPE_OBJECT,
248                          G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT,
249                                                 g_simple_async_result_async_result_iface_init))
250
251 static void
252 clear_op_res (GSimpleAsyncResult *simple)
253 {
254   if (simple->destroy_op_res)
255     simple->destroy_op_res (simple->op_res.v_pointer);
256   simple->destroy_op_res = NULL;
257   simple->op_res.v_ssize = 0;
258 }
259
260 static void
261 g_simple_async_result_finalize (GObject *object)
262 {
263   GSimpleAsyncResult *simple;
264
265   simple = G_SIMPLE_ASYNC_RESULT (object);
266
267   if (simple->source_object)
268     g_object_unref (simple->source_object);
269
270   if (simple->context)
271     g_main_context_unref (simple->context);
272
273   clear_op_res (simple);
274
275   if (simple->error)
276     g_error_free (simple->error);
277
278   G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize (object);
279 }
280
281 static void
282 g_simple_async_result_class_init (GSimpleAsyncResultClass *klass)
283 {
284   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
285  
286   gobject_class->finalize = g_simple_async_result_finalize;
287 }
288
289 static void
290 g_simple_async_result_init (GSimpleAsyncResult *simple)
291 {
292   simple->handle_cancellation = TRUE;
293
294   simple->context = g_main_context_get_thread_default ();
295   if (simple->context)
296     g_main_context_ref (simple->context);
297 }
298
299 /**
300  * g_simple_async_result_new:
301  * @source_object: a #GObject the asynchronous function was called with,
302  * or %NULL.
303  * @callback: a #GAsyncReadyCallback.
304  * @user_data: user data passed to @callback.
305  * @source_tag: the asynchronous function.
306  *
307  * Creates a #GSimpleAsyncResult.
308  *
309  * Returns: a #GSimpleAsyncResult.
310  **/
311 GSimpleAsyncResult *
312 g_simple_async_result_new (GObject             *source_object,
313                            GAsyncReadyCallback  callback,
314                            gpointer             user_data,
315                            gpointer             source_tag)
316 {
317   GSimpleAsyncResult *simple;
318
319   g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
320
321   simple = g_object_new (G_TYPE_SIMPLE_ASYNC_RESULT, NULL);
322   simple->callback = callback;
323   if (source_object)
324     simple->source_object = g_object_ref (source_object);
325   else
326     simple->source_object = NULL;
327   simple->user_data = user_data;
328   simple->source_tag = source_tag;
329  
330   return simple;
331 }
332
333 /**
334  * g_simple_async_result_new_from_error:
335  * @source_object: a #GObject, or %NULL.
336  * @callback: a #GAsyncReadyCallback.
337  * @user_data: user data passed to @callback.
338  * @error: a #GError location.
339  *
340  * Creates a #GSimpleAsyncResult from an error condition.
341  *
342  * Returns: a #GSimpleAsyncResult.
343  **/
344 GSimpleAsyncResult *
345 g_simple_async_result_new_from_error (GObject             *source_object,
346                                       GAsyncReadyCallback  callback,
347                                       gpointer             user_data,
348                                       GError              *error)
349 {
350   GSimpleAsyncResult *simple;
351
352   g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
353
354   simple = g_simple_async_result_new (source_object,
355                                       callback,
356                                       user_data, NULL);
357   g_simple_async_result_set_from_error (simple, error);
358
359   return simple;
360 }
361
362 /**
363  * g_simple_async_result_new_error:
364  * @source_object: a #GObject, or %NULL.
365  * @callback: a #GAsyncReadyCallback.
366  * @user_data: user data passed to @callback.
367  * @domain: a #GQuark.
368  * @code: an error code.
369  * @format: a string with format characters.
370  * @...: a list of values to insert into @format.
371  *
372  * Creates a new #GSimpleAsyncResult with a set error.
373  *
374  * Returns: a #GSimpleAsyncResult.
375  **/
376 GSimpleAsyncResult *
377 g_simple_async_result_new_error (GObject             *source_object,
378                                  GAsyncReadyCallback  callback,
379                                  gpointer             user_data,
380                                  GQuark               domain,
381                                  gint                 code,
382                                  const char          *format,
383                                  ...)
384 {
385   GSimpleAsyncResult *simple;
386   va_list args;
387  
388   g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
389   g_return_val_if_fail (domain != 0, NULL);
390   g_return_val_if_fail (format != NULL, NULL);
391
392   simple = g_simple_async_result_new (source_object,
393                                       callback,
394                                       user_data, NULL);
395
396   va_start (args, format);
397   g_simple_async_result_set_error_va (simple, domain, code, format, args);
398   va_end (args);
399  
400   return simple;
401 }
402
403
404 static gpointer
405 g_simple_async_result_get_user_data (GAsyncResult *res)
406 {
407   return G_SIMPLE_ASYNC_RESULT (res)->user_data;
408 }
409
410 static GObject *
411 g_simple_async_result_get_source_object (GAsyncResult *res)
412 {
413   if (G_SIMPLE_ASYNC_RESULT (res)->source_object)
414     return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object);
415   return NULL;
416 }
417
418 static void
419 g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface)
420 {
421   iface->get_user_data = g_simple_async_result_get_user_data;
422   iface->get_source_object = g_simple_async_result_get_source_object;
423 }
424
425 /**
426  * g_simple_async_result_set_handle_cancellation:
427  * @simple: a #GSimpleAsyncResult.
428  * @handle_cancellation: a #gboolean.
429  *
430  * Sets whether to handle cancellation within the asynchronous operation.
431  *
432  **/
433 void
434 g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple,
435                                                gboolean            handle_cancellation)
436 {
437   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
438   simple->handle_cancellation = handle_cancellation;
439 }
440
441 /**
442  * g_simple_async_result_get_source_tag:
443  * @simple: a #GSimpleAsyncResult.
444  *
445  * Gets the source tag for the #GSimpleAsyncResult.
446  *
447  * Returns: a #gpointer to the source object for the #GSimpleAsyncResult.
448  **/
449 gpointer
450 g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple)
451 {
452   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
453   return simple->source_tag;
454 }
455
456 /**
457  * g_simple_async_result_propagate_error:
458  * @simple: a #GSimpleAsyncResult.
459  * @dest: a location to propegate the error to.
460  *
461  * Propagates an error from within the simple asynchronous result to
462  * a given destination.
463  *
464  * Returns: %TRUE if the error was propagated to @dest. %FALSE otherwise.
465  **/
466 gboolean
467 g_simple_async_result_propagate_error (GSimpleAsyncResult  *simple,
468                                        GError             **dest)
469 {
470   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
471
472   if (simple->failed)
473     {
474       g_propagate_error (dest, simple->error);
475       simple->error = NULL;
476       return TRUE;
477     }
478
479   return FALSE;
480 }
481
482 /**
483  * g_simple_async_result_set_op_res_gpointer:
484  * @simple: a #GSimpleAsyncResult.
485  * @op_res: a pointer result from an asynchronous function.
486  * @destroy_op_res: a #GDestroyNotify function.
487  *
488  * Sets the operation result within the asynchronous result to a pointer.
489  **/
490 void
491 g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple,
492                                            gpointer            op_res,
493                                            GDestroyNotify      destroy_op_res)
494 {
495   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
496
497   clear_op_res (simple);
498   simple->op_res.v_pointer = op_res;
499   simple->destroy_op_res = destroy_op_res;
500 }
501
502 /**
503  * g_simple_async_result_get_op_res_gpointer:
504  * @simple: a #GSimpleAsyncResult.
505  *
506  * Gets a pointer result as returned by the asynchronous function.
507  *
508  * Returns: a pointer from the result.
509  **/
510 gpointer
511 g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple)
512 {
513   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
514   return simple->op_res.v_pointer;
515 }
516
517 /**
518  * g_simple_async_result_set_op_res_gssize:
519  * @simple: a #GSimpleAsyncResult.
520  * @op_res: a #gssize.
521  *
522  * Sets the operation result within the asynchronous result to
523  * the given @op_res.
524  **/
525 void
526 g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple,
527                                          gssize              op_res)
528 {
529   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
530   clear_op_res (simple);
531   simple->op_res.v_ssize = op_res;
532 }
533
534 /**
535  * g_simple_async_result_get_op_res_gssize:
536  * @simple: a #GSimpleAsyncResult.
537  *
538  * Gets a gssize from the asynchronous result.
539  *
540  * Returns: a gssize returned from the asynchronous function.
541  **/
542 gssize
543 g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple)
544 {
545   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0);
546   return simple->op_res.v_ssize;
547 }
548
549 /**
550  * g_simple_async_result_set_op_res_gboolean:
551  * @simple: a #GSimpleAsyncResult.
552  * @op_res: a #gboolean.
553  *
554  * Sets the operation result to a boolean within the asynchronous result.
555  **/
556 void
557 g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple,
558                                            gboolean            op_res)
559 {
560   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
561   clear_op_res (simple);
562   simple->op_res.v_boolean = !!op_res;
563 }
564
565 /**
566  * g_simple_async_result_get_op_res_gboolean:
567  * @simple: a #GSimpleAsyncResult.
568  *
569  * Gets the operation result boolean from within the asynchronous result.
570  *
571  * Returns: %TRUE if the operation's result was %TRUE, %FALSE
572  *     if the operation's result was %FALSE.
573  **/
574 gboolean
575 g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple)
576 {
577   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
578   return simple->op_res.v_boolean;
579 }
580
581 /**
582  * g_simple_async_result_set_from_error:
583  * @simple: a #GSimpleAsyncResult.
584  * @error: #GError.
585  *
586  * Sets the result from a #GError.
587  **/
588 void
589 g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
590                                       const GError       *error)
591 {
592   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
593   g_return_if_fail (error != NULL);
594
595   if (simple->error)
596     g_error_free (simple->error);
597   simple->error = g_error_copy (error);
598   simple->failed = TRUE;
599 }
600
601 /**
602  * g_simple_async_result_set_error_va:
603  * @simple: a #GSimpleAsyncResult.
604  * @domain: a #GQuark (usually #G_IO_ERROR).
605  * @code: an error code.
606  * @format: a formatted error reporting string.
607  * @args: va_list of arguments.
608  *
609  * Sets an error within the asynchronous result without a #GError.
610  * Unless writing a binding, see g_simple_async_result_set_error().
611  **/
612 void
613 g_simple_async_result_set_error_va (GSimpleAsyncResult *simple,
614                                     GQuark              domain,
615                                     gint                code,
616                                     const char         *format,
617                                     va_list             args)
618 {
619   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
620   g_return_if_fail (domain != 0);
621   g_return_if_fail (format != NULL);
622
623   if (simple->error)
624     g_error_free (simple->error);
625   simple->error = g_error_new_valist (domain, code, format, args);
626   simple->failed = TRUE;
627 }
628
629 /**
630  * g_simple_async_result_set_error:
631  * @simple: a #GSimpleAsyncResult.
632  * @domain: a #GQuark (usually #G_IO_ERROR).
633  * @code: an error code.
634  * @format: a formatted error reporting string.
635  * @...: a list of variables to fill in @format.
636  *
637  * Sets an error within the asynchronous result without a #GError.
638  **/
639 void
640 g_simple_async_result_set_error (GSimpleAsyncResult *simple,
641                                  GQuark              domain,
642                                  gint                code,
643                                  const char         *format,
644                                  ...)
645 {
646   va_list args;
647
648   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
649   g_return_if_fail (domain != 0);
650   g_return_if_fail (format != NULL);
651
652   va_start (args, format);
653   g_simple_async_result_set_error_va (simple, domain, code, format, args);
654   va_end (args);
655 }
656
657 /**
658  * g_simple_async_result_complete:
659  * @simple: a #GSimpleAsyncResult.
660  *
661  * Completes an asynchronous I/O job immediately. Must be called in
662  * the thread where the asynchronous result was to be delivered, as it
663  * invokes the callback directly. If you are in a different thread use
664  * g_simple_async_result_complete_in_idle().
665  *
666  * Calling this function takes a reference to @simple for as long as
667  * is needed to complete the call.
668  **/
669 void
670 g_simple_async_result_complete (GSimpleAsyncResult *simple)
671 {
672 #ifndef G_DISABLE_CHECKS
673   GSource *current_source;
674   GMainContext *current_context;
675 #endif
676
677   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
678
679 #ifndef G_DISABLE_CHECKS
680   current_source = g_main_current_source ();
681   if (current_source && !g_source_is_destroyed (current_source))
682     {
683       current_context = g_source_get_context (current_source);
684       if (current_context == g_main_context_default ())
685         current_context = NULL;
686       if (simple->context != current_context)
687         g_warning ("g_simple_async_result_complete() called from wrong context!");
688     }
689 #endif
690
691   if (simple->callback)
692     simple->callback (simple->source_object,
693                       G_ASYNC_RESULT (simple),
694                       simple->user_data);
695 }
696
697 static gboolean
698 complete_in_idle_cb (gpointer data)
699 {
700   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data);
701
702   g_simple_async_result_complete (simple);
703
704   return FALSE;
705 }
706
707 /**
708  * g_simple_async_result_complete_in_idle:
709  * @simple: a #GSimpleAsyncResult.
710  *
711  * Completes an asynchronous function in an idle handler in the <link
712  * linkend="g-main-context-push-thread-default">thread-default main
713  * loop</link> of the thread that @simple was initially created in.
714  *
715  * Calling this function takes a reference to @simple for as long as
716  * is needed to complete the call.
717  */
718 void
719 g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
720 {
721   GSource *source;
722
723   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
724
725   g_object_ref (simple);
726  
727   source = g_idle_source_new ();
728   g_source_set_priority (source, G_PRIORITY_DEFAULT);
729   g_source_set_callback (source, complete_in_idle_cb, simple, g_object_unref);
730
731   g_source_attach (source, simple->context);
732   g_source_unref (source);
733 }
734
735 typedef struct {
736   GSimpleAsyncResult *simple;
737   GCancellable *cancellable;
738   GSimpleAsyncThreadFunc func;
739 } RunInThreadData;
740
741
742 static gboolean
743 complete_in_idle_cb_for_thread (gpointer _data)
744 {
745   RunInThreadData *data = _data;
746   GSimpleAsyncResult *simple;
747
748   simple = data->simple;
749  
750   if (simple->handle_cancellation &&
751       g_cancellable_is_cancelled (data->cancellable))
752     g_simple_async_result_set_error (simple,
753                                      G_IO_ERROR,
754                                      G_IO_ERROR_CANCELLED,
755                                      "%s", _("Operation was cancelled"));
756  
757   g_simple_async_result_complete (simple);
758
759   if (data->cancellable)
760     g_object_unref (data->cancellable);
761   g_object_unref (data->simple);
762   g_free (data);
763  
764   return FALSE;
765 }
766
767 static gboolean
768 run_in_thread (GIOSchedulerJob *job,
769                GCancellable    *c,
770                gpointer         _data)
771 {
772   RunInThreadData *data = _data;
773   GSimpleAsyncResult *simple = data->simple;
774   GSource *source;
775  
776   if (simple->handle_cancellation &&
777       g_cancellable_is_cancelled (c))
778     g_simple_async_result_set_error (simple,
779                                      G_IO_ERROR,
780                                      G_IO_ERROR_CANCELLED,
781                                      "%s", _("Operation was cancelled"));
782   else
783     data->func (simple,
784                 simple->source_object,
785                 c);
786
787   source = g_idle_source_new ();
788   g_source_set_priority (source, G_PRIORITY_DEFAULT);
789   g_source_set_callback (source, complete_in_idle_cb_for_thread, data, NULL);
790
791   g_source_attach (source, simple->context);
792   g_source_unref (source);
793
794   return FALSE;
795 }
796
797 /**
798  * g_simple_async_result_run_in_thread:
799  * @simple: a #GSimpleAsyncResult.
800  * @func: a #GSimpleAsyncThreadFunc.
801  * @io_priority: the io priority of the request.
802  * @cancellable: optional #GCancellable object, %NULL to ignore.
803  *
804  * Runs the asynchronous job in a separate thread and then calls
805  * g_simple_async_result_complete_in_idle() on @simple to return
806  * the result to the appropriate main loop.
807  *
808  * Calling this function takes a reference to @simple for as long as
809  * is needed to run the job and report its completion.
810  */
811 void
812 g_simple_async_result_run_in_thread (GSimpleAsyncResult     *simple,
813                                      GSimpleAsyncThreadFunc  func,
814                                      int                     io_priority,
815                                      GCancellable           *cancellable)
816 {
817   RunInThreadData *data;
818
819   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
820   g_return_if_fail (func != NULL);
821
822   data = g_new (RunInThreadData, 1);
823   data->func = func;
824   data->simple = g_object_ref (simple);
825   data->cancellable = cancellable;
826   if (cancellable)
827     g_object_ref (cancellable);
828   g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
829 }
830
831 /**
832  * g_simple_async_result_is_valid:
833  * @result: the #GAsyncResult passed to the _finish function.
834  * @source: the #GObject passed to the _finish function.
835  * @source_tag: the asynchronous function.
836  *
837  * Ensures that the data passed to the _finish function of an async
838  * operation is consistent.  Three checks are performed.
839  *
840  * First, @result is checked to ensure that it is really a
841  * #GSimpleAsyncResult.  Second, @source is checked to ensure that it
842  * matches the source object of @result.  Third, @source_tag is
843  * checked to ensure that it is either %NULL (as it is when the result was
844  * created by g_simple_async_report_error_in_idle() or
845  * g_simple_async_report_gerror_in_idle()) or equal to the
846  * @source_tag argument given to g_simple_async_result_new() (which, by
847  * convention, is a pointer to the _async function corresponding to the
848  * _finish function from which this function is called).
849  *
850  * Returns: #TRUE if all checks passed or #FALSE if any failed.
851  **/
852 gboolean
853 g_simple_async_result_is_valid (GAsyncResult *result,
854                                 GObject      *source,
855                                 gpointer      source_tag)
856 {
857   GSimpleAsyncResult *simple;
858   GObject *cmp_source;
859
860   if (!G_IS_SIMPLE_ASYNC_RESULT (result))
861     return FALSE;
862   simple = (GSimpleAsyncResult *)result;
863
864   cmp_source = g_async_result_get_source_object (result);
865   if (cmp_source != source)
866     {
867       if (cmp_source != NULL)
868         g_object_unref (cmp_source);
869       return FALSE;
870     }
871   if (cmp_source != NULL)
872     g_object_unref (cmp_source);
873
874   return source_tag == NULL ||
875          source_tag == g_simple_async_result_get_source_tag (simple);
876 }
877
878 /**
879  * g_simple_async_report_error_in_idle:
880  * @object: a #GObject.
881  * @callback: a #GAsyncReadyCallback.
882  * @user_data: user data passed to @callback.
883  * @domain: a #GQuark containing the error domain (usually #G_IO_ERROR).
884  * @code: a specific error code.
885  * @format: a formatted error reporting string.
886  * @...: a list of variables to fill in @format.
887  *
888  * Reports an error in an asynchronous function in an idle function by
889  * directly setting the contents of the #GAsyncResult with the given error
890  * information.
891  **/
892 void
893 g_simple_async_report_error_in_idle (GObject             *object,
894                                      GAsyncReadyCallback  callback,
895                                      gpointer             user_data,
896                                      GQuark               domain,
897                                      gint                 code,
898                                      const char          *format,
899                                      ...)
900 {
901   GSimpleAsyncResult *simple;
902   va_list args;
903  
904   g_return_if_fail (G_IS_OBJECT (object));
905   g_return_if_fail (domain != 0);
906   g_return_if_fail (format != NULL);
907
908   simple = g_simple_async_result_new (object,
909                                       callback,
910                                       user_data, NULL);
911
912   va_start (args, format);
913   g_simple_async_result_set_error_va (simple, domain, code, format, args);
914   va_end (args);
915   g_simple_async_result_complete_in_idle (simple);
916   g_object_unref (simple);
917 }
918
919 /**
920  * g_simple_async_report_gerror_in_idle:
921  * @object: a #GObject.
922  * @callback: a #GAsyncReadyCallback.
923  * @user_data: user data passed to @callback.
924  * @error: the #GError to report
925  *
926  * Reports an error in an idle function. Similar to
927  * g_simple_async_report_error_in_idle(), but takes a #GError rather
928  * than building a new one.
929  **/
930 void
931 g_simple_async_report_gerror_in_idle (GObject *object,
932                                       GAsyncReadyCallback callback,
933                                       gpointer user_data,
934                                       GError *error)
935 {
936   GSimpleAsyncResult *simple;
937  
938   g_return_if_fail (G_IS_OBJECT (object));
939   g_return_if_fail (error != NULL);
940
941   simple = g_simple_async_result_new_from_error (object,
942                                                  callback,
943                                                  user_data,
944                                                  error);
945   g_simple_async_result_complete_in_idle (simple);
946   g_object_unref (simple);
947 }