1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
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.
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.
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.
20 * Author: Alexander Larsson <alexl@redhat.com>
25 #include <sys/types.h>
34 #include "gsimpleasyncresult.h"
35 #include "gasyncresult.h"
36 #include "gcancellable.h"
37 #include "gioscheduler.h"
38 #include <gio/gioerror.h>
44 * SECTION:gsimpleasyncresult
45 * @short_description: Simple asynchronous results implementation
47 * @see_also: #GAsyncResult
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.
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
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.
70 * GSimpleAsyncResults are tagged with the calling function to ensure
71 * that asynchronous functions and their finishing functions are used
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().
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).
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
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.
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.
113 static void g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface);
115 struct _GSimpleAsyncResult
117 GObject parent_instance;
119 GObject *source_object;
120 GAsyncReadyCallback callback;
124 gboolean handle_cancellation;
134 GDestroyNotify destroy_op_res;
137 struct _GSimpleAsyncResultClass
139 GObjectClass parent_class;
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))
148 clear_op_res (GSimpleAsyncResult *simple)
150 if (simple->destroy_op_res)
151 simple->destroy_op_res (simple->op_res.v_pointer);
152 simple->destroy_op_res = NULL;
153 simple->op_res.v_ssize = 0;
157 g_simple_async_result_finalize (GObject *object)
159 GSimpleAsyncResult *simple;
161 simple = G_SIMPLE_ASYNC_RESULT (object);
163 if (simple->source_object)
164 g_object_unref (simple->source_object);
166 clear_op_res (simple);
169 g_error_free (simple->error);
171 G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize (object);
175 g_simple_async_result_class_init (GSimpleAsyncResultClass *klass)
177 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
179 gobject_class->finalize = g_simple_async_result_finalize;
183 g_simple_async_result_init (GSimpleAsyncResult *simple)
185 simple->handle_cancellation = TRUE;
189 * g_simple_async_result_new:
190 * @source_object: a #GObject the asynchronous function was called with,
192 * @callback: a #GAsyncReadyCallback.
193 * @user_data: user data passed to @callback.
194 * @source_tag: the asynchronous function.
196 * Creates a #GSimpleAsyncResult.
198 * Returns: a #GSimpleAsyncResult.
201 g_simple_async_result_new (GObject *source_object,
202 GAsyncReadyCallback callback,
206 GSimpleAsyncResult *simple;
208 g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
210 simple = g_object_new (G_TYPE_SIMPLE_ASYNC_RESULT, NULL);
211 simple->callback = callback;
213 simple->source_object = g_object_ref (source_object);
215 simple->source_object = NULL;
216 simple->user_data = user_data;
217 simple->source_tag = source_tag;
223 * g_simple_async_result_new_from_error:
224 * @source_object: a #GObject, or %NULL.
225 * @callback: a #GAsyncReadyCallback.
226 * @user_data: user data passed to @callback.
227 * @error: a #GError location.
229 * Creates a #GSimpleAsyncResult from an error condition.
231 * Returns: a #GSimpleAsyncResult.
234 g_simple_async_result_new_from_error (GObject *source_object,
235 GAsyncReadyCallback callback,
239 GSimpleAsyncResult *simple;
241 g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
243 simple = g_simple_async_result_new (source_object,
246 g_simple_async_result_set_from_error (simple, error);
252 * g_simple_async_result_new_error:
253 * @source_object: a #GObject, or %NULL.
254 * @callback: a #GAsyncReadyCallback.
255 * @user_data: user data passed to @callback.
256 * @domain: a #GQuark.
257 * @code: an error code.
258 * @format: a string with format characters.
259 * @...: a list of values to insert into @format.
261 * Creates a new #GSimpleAsyncResult with a set error.
263 * Returns: a #GSimpleAsyncResult.
266 g_simple_async_result_new_error (GObject *source_object,
267 GAsyncReadyCallback callback,
274 GSimpleAsyncResult *simple;
277 g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
278 g_return_val_if_fail (domain != 0, NULL);
279 g_return_val_if_fail (format != NULL, NULL);
281 simple = g_simple_async_result_new (source_object,
285 va_start (args, format);
286 g_simple_async_result_set_error_va (simple, domain, code, format, args);
294 g_simple_async_result_get_user_data (GAsyncResult *res)
296 return G_SIMPLE_ASYNC_RESULT (res)->user_data;
300 g_simple_async_result_get_source_object (GAsyncResult *res)
302 if (G_SIMPLE_ASYNC_RESULT (res)->source_object)
303 return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object);
308 g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface)
310 iface->get_user_data = g_simple_async_result_get_user_data;
311 iface->get_source_object = g_simple_async_result_get_source_object;
315 * g_simple_async_result_set_handle_cancellation:
316 * @simple: a #GSimpleAsyncResult.
317 * @handle_cancellation: a #gboolean.
319 * Sets whether to handle cancellation within the asynchronous operation.
323 g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple,
324 gboolean handle_cancellation)
326 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
327 simple->handle_cancellation = handle_cancellation;
331 * g_simple_async_result_get_source_tag:
332 * @simple: a #GSimpleAsyncResult.
334 * Gets the source tag for the #GSimpleAsyncResult.
336 * Returns: a #gpointer to the source object for the #GSimpleAsyncResult.
339 g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple)
341 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
342 return simple->source_tag;
346 * g_simple_async_result_propagate_error:
347 * @simple: a #GSimpleAsyncResult.
348 * @dest: a location to propegate the error to.
350 * Propagates an error from within the simple asynchronous result to
351 * a given destination.
353 * Returns: %TRUE if the error was propegated to @dest. %FALSE otherwise.
356 g_simple_async_result_propagate_error (GSimpleAsyncResult *simple,
359 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
363 g_propagate_error (dest, simple->error);
364 simple->error = NULL;
372 * g_simple_async_result_set_op_res_gpointer:
373 * @simple: a #GSimpleAsyncResult.
374 * @op_res: a pointer result from an asynchronous function.
375 * @destroy_op_res: a #GDestroyNotify function.
377 * Sets the operation result within the asynchronous result to a pointer.
380 g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple,
382 GDestroyNotify destroy_op_res)
384 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
386 clear_op_res (simple);
387 simple->op_res.v_pointer = op_res;
388 simple->destroy_op_res = destroy_op_res;
392 * g_simple_async_result_get_op_res_gpointer:
393 * @simple: a #GSimpleAsyncResult.
395 * Gets a pointer result as returned by the asynchronous function.
397 * Returns: a pointer from the result.
400 g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple)
402 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
403 return simple->op_res.v_pointer;
407 * g_simple_async_result_set_op_res_gssize:
408 * @simple: a #GSimpleAsyncResult.
409 * @op_res: a #gssize.
411 * Sets the operation result within the asynchronous result to
415 g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple,
418 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
419 clear_op_res (simple);
420 simple->op_res.v_ssize = op_res;
424 * g_simple_async_result_get_op_res_gssize:
425 * @simple: a #GSimpleAsyncResult.
427 * Gets a gssize from the asynchronous result.
429 * Returns: a gssize returned from the asynchronous function.
432 g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple)
434 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0);
435 return simple->op_res.v_ssize;
439 * g_simple_async_result_set_op_res_gboolean:
440 * @simple: a #GSimpleAsyncResult.
441 * @op_res: a #gboolean.
443 * Sets the operation result to a boolean within the asynchronous result.
446 g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple,
449 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
450 clear_op_res (simple);
451 simple->op_res.v_boolean = !!op_res;
455 * g_simple_async_result_get_op_res_gboolean:
456 * @simple: a #GSimpleAsyncResult.
458 * Gets the operation result boolean from within the asynchronous result.
460 * Returns: %TRUE if the operation's result was %TRUE, %FALSE
461 * if the operation's result was %FALSE.
464 g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple)
466 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
467 return simple->op_res.v_boolean;
471 * g_simple_async_result_set_from_error:
472 * @simple: a #GSimpleAsyncResult.
475 * Sets the result from a #GError.
478 g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
481 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
482 g_return_if_fail (error != NULL);
485 g_error_free (simple->error);
486 simple->error = g_error_copy (error);
487 simple->failed = TRUE;
491 _g_error_new_valist (GQuark domain,
499 message = g_strdup_vprintf (format, args);
501 error = g_error_new_literal (domain, code, message);
508 * g_simple_async_result_set_error_va:
509 * @simple: a #GSimpleAsyncResult.
510 * @domain: a #GQuark (usually #G_IO_ERROR).
511 * @code: an error code.
512 * @format: a formatted error reporting string.
513 * @args: va_list of arguments.
515 * Sets an error within the asynchronous result without a #GError.
516 * Unless writing a binding, see g_simple_async_result_set_error().
519 g_simple_async_result_set_error_va (GSimpleAsyncResult *simple,
525 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
526 g_return_if_fail (domain != 0);
527 g_return_if_fail (format != NULL);
530 g_error_free (simple->error);
531 simple->error = _g_error_new_valist (domain, code, format, args);
532 simple->failed = TRUE;
536 * g_simple_async_result_set_error:
537 * @simple: a #GSimpleAsyncResult.
538 * @domain: a #GQuark (usually #G_IO_ERROR).
539 * @code: an error code.
540 * @format: a formatted error reporting string.
541 * @...: a list of variables to fill in @format.
543 * Sets an error within the asynchronous result without a #GError.
546 g_simple_async_result_set_error (GSimpleAsyncResult *simple,
554 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
555 g_return_if_fail (domain != 0);
556 g_return_if_fail (format != NULL);
558 va_start (args, format);
559 g_simple_async_result_set_error_va (simple, domain, code, format, args);
564 * g_simple_async_result_complete:
565 * @simple: a #GSimpleAsyncResult.
567 * Completes an asynchronous I/O job.
568 * Must be called in the main thread, as it invokes the callback that
569 * should be called in the main thread. If you are in a different thread
570 * use g_simple_async_result_complete_in_idle().
573 g_simple_async_result_complete (GSimpleAsyncResult *simple)
575 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
577 if (simple->callback)
578 simple->callback (simple->source_object,
579 G_ASYNC_RESULT (simple),
584 complete_in_idle_cb (gpointer data)
586 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data);
588 g_simple_async_result_complete (simple);
594 * g_simple_async_result_complete_in_idle:
595 * @simple: a #GSimpleAsyncResult.
597 * Completes an asynchronous function in the main event loop using
601 g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
606 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
608 g_object_ref (simple);
610 source = g_idle_source_new ();
611 g_source_set_priority (source, G_PRIORITY_DEFAULT);
612 g_source_set_callback (source, complete_in_idle_cb, simple, g_object_unref);
614 id = g_source_attach (source, NULL);
615 g_source_unref (source);
619 GSimpleAsyncResult *simple;
620 GCancellable *cancellable;
621 GSimpleAsyncThreadFunc func;
626 complete_in_idle_cb_for_thread (gpointer _data)
628 RunInThreadData *data = _data;
629 GSimpleAsyncResult *simple;
631 simple = data->simple;
633 if (simple->handle_cancellation &&
634 g_cancellable_is_cancelled (data->cancellable))
635 g_simple_async_result_set_error (simple,
637 G_IO_ERROR_CANCELLED,
638 "%s", _("Operation was cancelled"));
640 g_simple_async_result_complete (simple);
642 if (data->cancellable)
643 g_object_unref (data->cancellable);
644 g_object_unref (data->simple);
651 run_in_thread (GIOSchedulerJob *job,
655 RunInThreadData *data = _data;
656 GSimpleAsyncResult *simple = data->simple;
660 if (simple->handle_cancellation &&
661 g_cancellable_is_cancelled (c))
662 g_simple_async_result_set_error (simple,
664 G_IO_ERROR_CANCELLED,
665 "%s", _("Operation was cancelled"));
668 simple->source_object,
671 source = g_idle_source_new ();
672 g_source_set_priority (source, G_PRIORITY_DEFAULT);
673 g_source_set_callback (source, complete_in_idle_cb_for_thread, data, NULL);
675 id = g_source_attach (source, NULL);
676 g_source_unref (source);
682 * g_simple_async_result_run_in_thread:
683 * @simple: a #GSimpleAsyncResult.
684 * @func: a #GSimpleAsyncThreadFunc.
685 * @io_priority: the io priority of the request.
686 * @cancellable: optional #GCancellable object, %NULL to ignore.
688 * Runs the asynchronous job in a separated thread.
691 g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple,
692 GSimpleAsyncThreadFunc func,
694 GCancellable *cancellable)
696 RunInThreadData *data;
698 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
699 g_return_if_fail (func != NULL);
701 data = g_new (RunInThreadData, 1);
703 data->simple = g_object_ref (simple);
704 data->cancellable = cancellable;
706 g_object_ref (cancellable);
707 g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
711 * g_simple_async_result_is_valid:
712 * @result: the #GAsyncResult passed to the _finish function.
713 * @source: the #GObject passed to the _finish function.
714 * @source_tag: the asynchronous function.
716 * Ensures that the data passed to the _finish function of an async
717 * operation is consistent. Three checks are performed.
719 * First, @result is checked to ensure that it is really a
720 * #GSimpleAsyncResult. Second, @source is checked to ensure that it
721 * matches the source object of @result. Third, @source_tag is
722 * checked to ensure that it is equal to the source_tag argument given
723 * to g_simple_async_result_new() (which, by convention, is a pointer
724 * to the _async function corresponding to the _finish function from
725 * which this function is called).
727 * Returns: #TRUE if all checks passed or #FALSE if any failed.
730 g_simple_async_result_is_valid (GAsyncResult *result,
734 GSimpleAsyncResult *simple;
737 if (!G_IS_SIMPLE_ASYNC_RESULT (result))
739 simple = (GSimpleAsyncResult *)result;
741 cmp_source = g_async_result_get_source_object (result);
742 if (cmp_source != source)
744 g_object_unref (cmp_source);
747 g_object_unref (cmp_source);
749 return source_tag == g_simple_async_result_get_source_tag (simple);
753 * g_simple_async_report_error_in_idle:
754 * @object: a #GObject.
755 * @callback: a #GAsyncReadyCallback.
756 * @user_data: user data passed to @callback.
757 * @domain: a #GQuark containing the error domain (usually #G_IO_ERROR).
758 * @code: a specific error code.
759 * @format: a formatted error reporting string.
760 * @...: a list of variables to fill in @format.
762 * Reports an error in an asynchronous function in an idle function by
763 * directly setting the contents of the #GAsyncResult with the given error
767 g_simple_async_report_error_in_idle (GObject *object,
768 GAsyncReadyCallback callback,
775 GSimpleAsyncResult *simple;
778 g_return_if_fail (G_IS_OBJECT (object));
779 g_return_if_fail (domain != 0);
780 g_return_if_fail (format != NULL);
782 simple = g_simple_async_result_new (object,
786 va_start (args, format);
787 g_simple_async_result_set_error_va (simple, domain, code, format, args);
789 g_simple_async_result_complete_in_idle (simple);
790 g_object_unref (simple);
794 * g_simple_async_report_gerror_in_idle:
795 * @object: a #GObject.
796 * @callback: a #GAsyncReadyCallback.
797 * @user_data: user data passed to @callback.
798 * @error: the #GError to report
800 * Reports an error in an idle function. Similar to
801 * g_simple_async_report_error_in_idle(), but takes a #GError rather
802 * than building a new one.
805 g_simple_async_report_gerror_in_idle (GObject *object,
806 GAsyncReadyCallback callback,
810 GSimpleAsyncResult *simple;
812 g_return_if_fail (G_IS_OBJECT (object));
813 g_return_if_fail (error != NULL);
815 simple = g_simple_async_result_new_from_error (object,
819 g_simple_async_result_complete_in_idle (simple);
820 g_object_unref (simple);
823 #define __G_SIMPLE_ASYNC_RESULT_C__
824 #include "gioaliasdef.c"