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>
32 #include "gsimpleasyncresult.h"
33 #include "gioscheduler.h"
34 #include <gio/gioerror.h>
40 * SECTION:gsimpleasyncresult
41 * @short_description: simple asynchronous results implementation
42 * @see_also: #GAsyncResult
44 * Implements #GAsyncResult for simple cases. Most of the time, this
45 * will be all an application needs, and will be used transparently.
46 * Because of this, #GSimpleAsyncResult is used throughout GIO for
47 * handling asynchronous functions.
49 * GSimpleAsyncResult handles #GAsyncReadyCallback<!-- -->s, error reporting,
50 * operation cancellation and the final state of an operation, completely
51 * transparent to the application. Results can be returned as a pointer e.g.
52 * for functions that return data that is collected asynchronously,
53 * a boolean value for checking the success or failure of an operation,
54 * or a #gssize for operations which return the number of bytes modified
55 * by the operation; all of the simple return cases are covered.
57 * Most of the time, an application will not need to know of the details
58 * of this API; it is handled transparently, and any necessary operations are
59 * handled by #GAsyncResult's interface. However, if implementing a new GIO
60 * module, for writing language bindings, or for complex applications that
61 * need better control of how asynchronous operations are completed, it is
62 * important to understand this functionality.
64 * To create a new #GSimpleAsyncResult, call g_simple_async_result_new(). If
65 * the result needs to be created for a #GError, use
66 * g_simple_async_result_new_from_error(). If a #GError is not available (e.g.
67 * the asynchronous operation's doesn't take a #GError argument), but the result
68 * still needs to be created for an error condition, use
69 * g_simple_async_result_new_error() (or g_simple_async_result_set_error_va()
70 * if your application or binding requires passing a variable argument list
71 * directly), and the error can then be propegated through the use of
72 * g_simple_async_result_propagate_error().
74 * An asynchronous operation can be made to ignore a cancellation event by calling
75 * g_simple_async_result_set_handle_cancellation() with a #GSimpleAsyncResult
76 * for the operation and %FALSE.
78 * GSimpleAsyncResult can integrate into GLib's Main Event Loop <!-- TODO: Crosslink -->,
79 * or it can use #GThread<!-- -->s if available. g_simple_async_result_complete()
80 * will finish an I/O task directly within the main event loop.
81 * g_simple_async_result_complete_in_idle() will integrate the I/O task into the
82 * main event loop as an idle function and g_simple_async_result_run_in_thread()
83 * will run the job in a separate thread.
85 * To set the results of an asynchronous function,
86 * g_simple_async_result_set_op_res_gpointer(),
87 * g_simple_async_result_set_op_res_gboolean(), and
88 * g_simple_async_result_set_op_res_gssize()
89 * are provided, setting the operation's result to a gpointer, gboolean, or
90 * gssize, respectively.
92 * Likewise, to get the result of an asynchronous function,
93 * g_simple_async_result_get_op_res_gpointer(),
94 * g_simple_async_result_get_op_res_gboolean(), and
95 * g_simple_async_result_get_op_res_gssize() are
96 * provided, getting the operation's result as a gpointer, gboolean, and
97 * gssize, respectively.
100 static void g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface);
102 struct _GSimpleAsyncResult
104 GObject parent_instance;
106 GObject *source_object;
107 GAsyncReadyCallback callback;
111 gboolean handle_cancellation;
121 GDestroyNotify destroy_op_res;
124 struct _GSimpleAsyncResultClass
126 GObjectClass parent_class;
130 G_DEFINE_TYPE_WITH_CODE (GSimpleAsyncResult, g_simple_async_result, G_TYPE_OBJECT,
131 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT,
132 g_simple_async_result_async_result_iface_init))
135 g_simple_async_result_finalize (GObject *object)
137 GSimpleAsyncResult *simple;
139 simple = G_SIMPLE_ASYNC_RESULT (object);
141 if (simple->source_object)
142 g_object_unref (simple->source_object);
144 if (simple->destroy_op_res)
145 simple->destroy_op_res (simple->op_res.v_pointer);
148 g_error_free (simple->error);
150 if (G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize)
151 (*G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize) (object);
155 g_simple_async_result_class_init (GSimpleAsyncResultClass *klass)
157 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
159 gobject_class->finalize = g_simple_async_result_finalize;
163 g_simple_async_result_init (GSimpleAsyncResult *simple)
165 simple->handle_cancellation = TRUE;
169 * g_simple_async_result_new:
170 * @source_object: a #GObject.
171 * @callback: a #GAsyncReadyCallback.
172 * @user_data: user data passed to @callback.
175 * Creates a #GSimpleAsyncResult.
177 * Returns: a #GSimpleAsyncResult.
180 g_simple_async_result_new (GObject *source_object,
181 GAsyncReadyCallback callback,
185 GSimpleAsyncResult *simple;
187 g_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
189 simple = g_object_new (G_TYPE_SIMPLE_ASYNC_RESULT, NULL);
190 simple->callback = callback;
191 simple->source_object = g_object_ref (source_object);
192 simple->user_data = user_data;
193 simple->source_tag = source_tag;
199 * g_simple_async_result_new_from_error:
200 * @source_object: a #GObject.
201 * @callback: a #GAsyncReadyCallback.
202 * @user_data: user data passed to @callback.
203 * @error: a #GError location.
205 * Creates a #GSimpleAsyncResult from an error condition.
207 * Returns: a #GSimpleAsyncResult.
210 g_simple_async_result_new_from_error (GObject *source_object,
211 GAsyncReadyCallback callback,
215 GSimpleAsyncResult *simple;
217 g_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
219 simple = g_simple_async_result_new (source_object,
222 g_simple_async_result_set_from_error (simple, error);
228 * g_simple_async_result_new_error:
229 * @source_object: a #GObject.
230 * @callback: a #GAsyncReadyCallback.
231 * @user_data: user data passed to @callback.
232 * @domain: a #GQuark.
233 * @code: an error code.
234 * @format: a string with format characters.
235 * @Varargs: a list of values to insert into @format.
237 * Creates a new #GSimpleAsyncResult with a set error.
239 * Returns: a #GSimpleAsyncResult.
242 g_simple_async_result_new_error (GObject *source_object,
243 GAsyncReadyCallback callback,
250 GSimpleAsyncResult *simple;
253 g_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
254 g_return_val_if_fail (domain != 0, NULL);
255 g_return_val_if_fail (format != NULL, NULL);
257 simple = g_simple_async_result_new (source_object,
261 va_start (args, format);
262 g_simple_async_result_set_error_va (simple, domain, code, format, args);
270 g_simple_async_result_get_user_data (GAsyncResult *res)
272 return G_SIMPLE_ASYNC_RESULT (res)->user_data;
276 g_simple_async_result_get_source_object (GAsyncResult *res)
278 if (G_SIMPLE_ASYNC_RESULT (res)->source_object)
279 return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object);
284 g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface)
286 iface->get_user_data = g_simple_async_result_get_user_data;
287 iface->get_source_object = g_simple_async_result_get_source_object;
291 * g_simple_async_result_set_handle_cancellation:
292 * @simple: a #GSimpleAsyncResult.
293 * @handle_cancellation: a #gboolean.
295 * Sets whether to handle cancellation within the asynchronous operation.
299 g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple,
300 gboolean handle_cancellation)
302 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
303 simple->handle_cancellation = handle_cancellation;
307 * g_simple_async_result_get_source_tag:
308 * @simple: a #GSimpleAsyncResult.
310 * Gets the source tag for the #GSimpleAsyncResult.
312 * Returns: a #gpointer to the source object for the #GSimpleAsyncResult.
315 g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple)
317 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
318 return simple->source_tag;
322 * g_simple_async_result_propagate_error:
323 * @simple: a #GSimpleAsyncResult.
324 * @dest: a location to propegate the error to.
326 * Propegates an error from within the simple asynchronous result to
327 * a given destination.
329 * Returns: %TRUE if the error was propegated to @dest. %FALSE otherwise.
332 g_simple_async_result_propagate_error (GSimpleAsyncResult *simple,
335 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
339 g_propagate_error (dest, simple->error);
340 simple->error = NULL;
347 * g_simple_async_result_set_op_res_gpointer:
348 * @simple: a #GSimpleAsyncResult.
349 * @op_res: a pointer result from an asynchronous function.
350 * @destroy_op_res: a #GDestroyNotify function.
352 * Sets the operation result within the asynchronous result to a pointer.
355 g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple,
357 GDestroyNotify destroy_op_res)
359 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
361 simple->op_res.v_pointer = op_res;
362 simple->destroy_op_res = destroy_op_res;
366 * g_simple_async_result_get_op_res_gpointer:
367 * @simple: a #GSimpleAsyncResult.
369 * Gets a pointer result as returned by the asynchronous function.
371 * Returns: a pointer from the result.
374 g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple)
376 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
377 return simple->op_res.v_pointer;
381 * g_simple_async_result_set_op_res_gssize:
382 * @simple: a #GSimpleAsyncResult.
383 * @op_res: a #gssize.
385 * Sets the operation result within the asynchronous result to the given @op_res.
388 g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple,
391 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
392 simple->op_res.v_ssize = op_res;
396 * g_simple_async_result_get_op_res_gssize:
397 * @simple: a #GSimpleAsyncResult.
399 * Gets a gssize from the asynchronous result.
401 * Returns: a gssize returned from the asynchronous function.
404 g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple)
406 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0);
407 return simple->op_res.v_ssize;
411 * g_simple_async_result_set_op_res_gboolean:
412 * @simple: a #GSimpleAsyncResult.
413 * @op_res: a #gboolean.
415 * Sets the operation result to a boolean within the asynchronous result.
419 g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple,
422 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
423 simple->op_res.v_boolean = !!op_res;
427 * g_simple_async_result_get_op_res_gboolean:
428 * @simple: a #GSimpleAsyncResult.
430 * Gets the operation result boolean from within the asynchronous result.
432 * Returns: %TRUE if the operation's result was %TRUE, %FALSE if the operation's
436 g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple)
438 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
439 return simple->op_res.v_boolean;
443 * g_simple_async_result_set_from_error:
444 * @simple: a #GSimpleAsyncResult.
447 * Sets the result from a #GError.
450 g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
453 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
454 g_return_if_fail (error != NULL);
456 simple->error = g_error_copy (error);
457 simple->failed = TRUE;
461 _g_error_new_valist (GQuark domain,
469 message = g_strdup_vprintf (format, args);
471 error = g_error_new_literal (domain, code, message);
478 * g_simple_async_result_set_error_va:
479 * @simple: a #GSimpleAsyncResult.
480 * @domain: a #GQuark (usually #G_IO_ERROR).
481 * @code: an error code.
482 * @format: a formatted error reporting string.
483 * @args: va_list of arguments.
485 * Sets an error within the asynchronous result without a #GError. Unless
486 * writing a binding, see g_simple_async_result_set_error().
489 g_simple_async_result_set_error_va (GSimpleAsyncResult *simple,
495 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
496 g_return_if_fail (domain != 0);
497 g_return_if_fail (format != NULL);
499 simple->error = _g_error_new_valist (domain, code, format, args);
500 simple->failed = TRUE;
504 * g_simple_async_result_set_error:
505 * @simple: a #GSimpleAsyncResult.
506 * @domain: a #GQuark (usually #G_IO_ERROR).
507 * @code: an error code.
508 * @format: a formatted error reporting string.
509 * @Varargs: a list of variables to fill in @format.
511 * Sets an error within the asynchronous result without a #GError.
515 g_simple_async_result_set_error (GSimpleAsyncResult *simple,
523 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
524 g_return_if_fail (domain != 0);
525 g_return_if_fail (format != NULL);
527 va_start (args, format);
528 g_simple_async_result_set_error_va (simple, domain, code, format, args);
533 * g_simple_async_result_complete:
534 * @simple: a #GSimpleAsyncResult.
536 * Completes an asynchronous I/O job.
540 g_simple_async_result_complete (GSimpleAsyncResult *simple)
542 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
544 if (simple->callback)
545 simple->callback (simple->source_object,
546 G_ASYNC_RESULT (simple),
551 complete_in_idle_cb (gpointer data)
553 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data);
555 g_simple_async_result_complete (simple);
561 * g_simple_async_result_complete_in_idle:
562 * @simple: a #GSimpleAsyncResult.
564 * Completes an asynchronous function in the main event loop using
569 g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
574 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
576 g_object_ref (simple);
578 source = g_idle_source_new ();
579 g_source_set_priority (source, G_PRIORITY_DEFAULT);
580 g_source_set_callback (source, complete_in_idle_cb, simple, g_object_unref);
582 id = g_source_attach (source, NULL);
583 g_source_unref (source);
587 GSimpleAsyncResult *simple;
588 GSimpleAsyncThreadFunc func;
592 run_in_thread (GIOJob *job,
596 RunInThreadData *data = _data;
597 GSimpleAsyncResult *simple = data->simple;
599 if (simple->handle_cancellation &&
600 g_cancellable_is_cancelled (c))
602 g_simple_async_result_set_error (simple,
604 G_IO_ERROR_CANCELLED,
605 _("Operation was cancelled"));
610 simple->source_object,
614 g_simple_async_result_complete_in_idle (data->simple);
615 g_object_unref (data->simple);
620 * g_simple_async_result_run_in_thread:
621 * @simple: a #GSimpleAsyncResult.
622 * @func: a #GSimpleAsyncThreadFunc.
623 * @io_priority: the io priority of the request.
624 * @cancellable: optional #GCancellable object, %NULL to ignore.
626 * Runs the asynchronous job in a separated thread.
630 g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple,
631 GSimpleAsyncThreadFunc func,
633 GCancellable *cancellable)
635 RunInThreadData *data;
637 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
638 g_return_if_fail (func != NULL);
640 data = g_new (RunInThreadData, 1);
642 data->simple = g_object_ref (simple);
643 g_schedule_io_job (run_in_thread, data, NULL, io_priority, cancellable);
647 * g_simple_async_report_error_in_idle:
649 * @callback: a #GAsyncReadyCallback.
650 * @user_data: user data passed to @callback.
651 * @domain: a #GQuark containing the error domain (usually #G_IO_ERROR).
652 * @code: a specific error code.
653 * @format: a formatted error reporting string.
654 * @Varargs: a list of variables to fill in @format.
656 * Reports an error in an idle function.
660 g_simple_async_report_error_in_idle (GObject *object,
661 GAsyncReadyCallback callback,
668 GSimpleAsyncResult *simple;
671 g_return_if_fail (G_IS_OBJECT (object));
672 g_return_if_fail (domain != 0);
673 g_return_if_fail (format != NULL);
675 simple = g_simple_async_result_new (object,
679 va_start (args, format);
680 g_simple_async_result_set_error_va (simple, domain, code, format, args);
682 g_simple_async_result_complete_in_idle (simple);
683 g_object_unref (simple);
686 #define __G_SIMPLE_ASYNC_RESULT_C__
687 #include "gioaliasdef.c"