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