Fix the build
[glib.git] / gio / gsimpleasyncresult.c
blob29666f16092502c898f3d4e4b0e10f1c2b8a926f
1 /* GIO - GLib Input, Output and Streaming Library
2 *
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>
23 #include <config.h>
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
34 #include "gsimpleasyncresult.h"
35 #include "gioscheduler.h"
36 #include <gio/gioerror.h>
37 #include "glibintl.h"
39 #include "gioalias.h"
41 /**
42 * SECTION:gsimpleasyncresult
43 * @short_description: Simple asynchronous results implementation
44 * @include: gio/gio.h
45 * @see_also: #GAsyncResult
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.
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.
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.
68 * GSimpleAsyncResults are tagged with the calling function to ensure
69 * that asynchronous functions and their finishing functions are used
70 * together correctly.
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().
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.
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.
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.
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.
109 static void g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface);
111 struct _GSimpleAsyncResult
113 GObject parent_instance;
115 GObject *source_object;
116 GAsyncReadyCallback callback;
117 gpointer user_data;
118 GError *error;
119 gboolean failed;
120 gboolean handle_cancellation;
122 gpointer source_tag;
124 union {
125 gpointer v_pointer;
126 gboolean v_boolean;
127 gssize v_ssize;
128 } op_res;
130 GDestroyNotify destroy_op_res;
133 struct _GSimpleAsyncResultClass
135 GObjectClass parent_class;
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))
143 static void
144 g_simple_async_result_finalize (GObject *object)
146 GSimpleAsyncResult *simple;
148 simple = G_SIMPLE_ASYNC_RESULT (object);
150 if (simple->source_object)
151 g_object_unref (simple->source_object);
153 if (simple->destroy_op_res)
154 simple->destroy_op_res (simple->op_res.v_pointer);
156 if (simple->error)
157 g_error_free (simple->error);
159 if (G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize)
160 (*G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize) (object);
163 static void
164 g_simple_async_result_class_init (GSimpleAsyncResultClass *klass)
166 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
168 gobject_class->finalize = g_simple_async_result_finalize;
171 static void
172 g_simple_async_result_init (GSimpleAsyncResult *simple)
174 simple->handle_cancellation = TRUE;
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.
184 * Creates a #GSimpleAsyncResult.
186 * Returns: a #GSimpleAsyncResult.
188 GSimpleAsyncResult *
189 g_simple_async_result_new (GObject *source_object,
190 GAsyncReadyCallback callback,
191 gpointer user_data,
192 gpointer source_tag)
194 GSimpleAsyncResult *simple;
196 g_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
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;
204 return simple;
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.
214 * Creates a #GSimpleAsyncResult from an error condition.
216 * Returns: a #GSimpleAsyncResult.
218 GSimpleAsyncResult *
219 g_simple_async_result_new_from_error (GObject *source_object,
220 GAsyncReadyCallback callback,
221 gpointer user_data,
222 GError *error)
224 GSimpleAsyncResult *simple;
226 g_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
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);
233 return simple;
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.
246 * Creates a new #GSimpleAsyncResult with a set error.
248 * Returns: a #GSimpleAsyncResult.
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 ...)
259 GSimpleAsyncResult *simple;
260 va_list args;
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);
266 simple = g_simple_async_result_new (source_object,
267 callback,
268 user_data, NULL);
270 va_start (args, format);
271 g_simple_async_result_set_error_va (simple, domain, code, format, args);
272 va_end (args);
274 return simple;
278 static gpointer
279 g_simple_async_result_get_user_data (GAsyncResult *res)
281 return G_SIMPLE_ASYNC_RESULT (res)->user_data;
284 static GObject *
285 g_simple_async_result_get_source_object (GAsyncResult *res)
287 if (G_SIMPLE_ASYNC_RESULT (res)->source_object)
288 return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object);
289 return NULL;
292 static void
293 g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface)
295 iface->get_user_data = g_simple_async_result_get_user_data;
296 iface->get_source_object = g_simple_async_result_get_source_object;
300 * g_simple_async_result_set_handle_cancellation:
301 * @simple: a #GSimpleAsyncResult.
302 * @handle_cancellation: a #gboolean.
304 * Sets whether to handle cancellation within the asynchronous operation.
307 void
308 g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple,
309 gboolean handle_cancellation)
311 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
312 simple->handle_cancellation = handle_cancellation;
316 * g_simple_async_result_get_source_tag:
317 * @simple: a #GSimpleAsyncResult.
319 * Gets the source tag for the #GSimpleAsyncResult.
321 * Returns: a #gpointer to the source object for the #GSimpleAsyncResult.
323 gpointer
324 g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple)
326 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
327 return simple->source_tag;
331 * g_simple_async_result_propagate_error:
332 * @simple: a #GSimpleAsyncResult.
333 * @dest: a location to propegate the error to.
335 * Propagates an error from within the simple asynchronous result to
336 * a given destination.
338 * Returns: %TRUE if the error was propegated to @dest. %FALSE otherwise.
340 gboolean
341 g_simple_async_result_propagate_error (GSimpleAsyncResult *simple,
342 GError **dest)
344 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
346 if (simple->failed)
348 g_propagate_error (dest, simple->error);
349 simple->error = NULL;
350 return TRUE;
353 return FALSE;
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.
362 * Sets the operation result within the asynchronous result to a pointer.
364 void
365 g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple,
366 gpointer op_res,
367 GDestroyNotify destroy_op_res)
369 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
371 simple->op_res.v_pointer = op_res;
372 simple->destroy_op_res = destroy_op_res;
376 * g_simple_async_result_get_op_res_gpointer:
377 * @simple: a #GSimpleAsyncResult.
379 * Gets a pointer result as returned by the asynchronous function.
381 * Returns: a pointer from the result.
383 gpointer
384 g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple)
386 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
387 return simple->op_res.v_pointer;
391 * g_simple_async_result_set_op_res_gssize:
392 * @simple: a #GSimpleAsyncResult.
393 * @op_res: a #gssize.
395 * Sets the operation result within the asynchronous result to
396 * the given @op_res.
398 void
399 g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple,
400 gssize op_res)
402 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
403 simple->op_res.v_ssize = op_res;
407 * g_simple_async_result_get_op_res_gssize:
408 * @simple: a #GSimpleAsyncResult.
410 * Gets a gssize from the asynchronous result.
412 * Returns: a gssize returned from the asynchronous function.
414 gssize
415 g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple)
417 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0);
418 return simple->op_res.v_ssize;
422 * g_simple_async_result_set_op_res_gboolean:
423 * @simple: a #GSimpleAsyncResult.
424 * @op_res: a #gboolean.
426 * Sets the operation result to a boolean within the asynchronous result.
428 void
429 g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple,
430 gboolean op_res)
432 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
433 simple->op_res.v_boolean = !!op_res;
437 * g_simple_async_result_get_op_res_gboolean:
438 * @simple: a #GSimpleAsyncResult.
440 * Gets the operation result boolean from within the asynchronous result.
442 * Returns: %TRUE if the operation's result was %TRUE, %FALSE
443 * if the operation's result was %FALSE.
445 gboolean
446 g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple)
448 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
449 return simple->op_res.v_boolean;
453 * g_simple_async_result_set_from_error:
454 * @simple: a #GSimpleAsyncResult.
455 * @error: #GError.
457 * Sets the result from a #GError.
459 void
460 g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
461 GError *error)
463 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
464 g_return_if_fail (error != NULL);
466 simple->error = g_error_copy (error);
467 simple->failed = TRUE;
470 static GError*
471 _g_error_new_valist (GQuark domain,
472 gint code,
473 const char *format,
474 va_list args)
476 GError *error;
477 char *message;
479 message = g_strdup_vprintf (format, args);
481 error = g_error_new_literal (domain, code, message);
482 g_free (message);
484 return error;
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.
495 * Sets an error within the asynchronous result without a #GError.
496 * Unless writing a binding, see g_simple_async_result_set_error().
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)
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);
509 simple->error = _g_error_new_valist (domain, code, format, args);
510 simple->failed = TRUE;
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.
521 * Sets an error within the asynchronous result without a #GError.
523 void
524 g_simple_async_result_set_error (GSimpleAsyncResult *simple,
525 GQuark domain,
526 gint code,
527 const char *format,
528 ...)
530 va_list args;
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);
536 va_start (args, format);
537 g_simple_async_result_set_error_va (simple, domain, code, format, args);
538 va_end (args);
542 * g_simple_async_result_complete:
543 * @simple: a #GSimpleAsyncResult.
545 * Completes an asynchronous I/O job.
547 void
548 g_simple_async_result_complete (GSimpleAsyncResult *simple)
550 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
552 if (simple->callback)
553 simple->callback (simple->source_object,
554 G_ASYNC_RESULT (simple),
555 simple->user_data);
558 static gboolean
559 complete_in_idle_cb (gpointer data)
561 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data);
563 g_simple_async_result_complete (simple);
565 return FALSE;
569 * g_simple_async_result_complete_in_idle:
570 * @simple: a #GSimpleAsyncResult.
572 * Completes an asynchronous function in the main event loop using
573 * an idle function.
575 void
576 g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
578 GSource *source;
579 guint id;
581 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
583 g_object_ref (simple);
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);
589 id = g_source_attach (source, NULL);
590 g_source_unref (source);
593 typedef struct {
594 GSimpleAsyncResult *simple;
595 GSimpleAsyncThreadFunc func;
596 } RunInThreadData;
598 static gboolean
599 run_in_thread (GIOSchedulerJob *job,
600 GCancellable *c,
601 gpointer _data)
603 RunInThreadData *data = _data;
604 GSimpleAsyncResult *simple = data->simple;
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,
617 g_simple_async_result_complete_in_idle (data->simple);
618 g_object_unref (data->simple);
619 g_free (data);
621 return FALSE;
625 * g_simple_async_result_run_in_thread:
626 * @simple: a #GSimpleAsyncResult.
627 * @func: a #GSimpleAsyncThreadFunc.
628 * @io_priority: the io priority of the request.
629 * @cancellable: optional #GCancellable object, %NULL to ignore.
631 * Runs the asynchronous job in a separated thread.
633 void
634 g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple,
635 GSimpleAsyncThreadFunc func,
636 int io_priority,
637 GCancellable *cancellable)
639 RunInThreadData *data;
641 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
642 g_return_if_fail (func != NULL);
644 data = g_new (RunInThreadData, 1);
645 data->func = func;
646 data->simple = g_object_ref (simple);
647 g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
651 * g_simple_async_report_error_in_idle:
652 * @object: a #GObject.
653 * @callback: a #GAsyncReadyCallback.
654 * @user_data: user data passed to @callback.
655 * @domain: a #GQuark containing the error domain (usually #G_IO_ERROR).
656 * @code: a specific error code.
657 * @format: a formatted error reporting string.
658 * @...: a list of variables to fill in @format.
660 * Reports an error in an asynchronous function in an idle function by
661 * directly setting the contents of the #GAsyncResult with the given error
662 * information.
664 void
665 g_simple_async_report_error_in_idle (GObject *object,
666 GAsyncReadyCallback callback,
667 gpointer user_data,
668 GQuark domain,
669 gint code,
670 const char *format,
671 ...)
673 GSimpleAsyncResult *simple;
674 va_list args;
676 g_return_if_fail (G_IS_OBJECT (object));
677 g_return_if_fail (domain != 0);
678 g_return_if_fail (format != NULL);
680 simple = g_simple_async_result_new (object,
681 callback,
682 user_data, NULL);
684 va_start (args, format);
685 g_simple_async_result_set_error_va (simple, domain, code, format, args);
686 va_end (args);
687 g_simple_async_result_complete_in_idle (simple);
688 g_object_unref (simple);
692 * g_simple_async_report_gerror_in_idle:
693 * @object: a #GObject.
694 * @callback: a #GAsyncReadyCallback.
695 * @user_data: user data passed to @callback.
696 * @error: the #GError to report
698 * Reports an error in an idle function. Similar to
699 * g_simple_async_report_error_in_idle(), but takes a #GError rather
700 * than building a new one.
702 void
703 g_simple_async_report_gerror_in_idle (GObject *object,
704 GAsyncReadyCallback callback,
705 gpointer user_data,
706 GError *error)
708 GSimpleAsyncResult *simple;
710 g_return_if_fail (G_IS_OBJECT (object));
711 g_return_if_fail (error != NULL);
713 simple = g_simple_async_result_new_from_error (object,
714 callback,
715 user_data,
716 error);
717 g_simple_async_result_complete_in_idle (simple);
718 g_object_unref (simple);
721 #define __G_SIMPLE_ASYNC_RESULT_C__
722 #include "gioaliasdef.c"