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