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