Added. Added. Added. Added.
[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  * 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().
73  * 
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. 
77  * 
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.
84  * 
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.
91  * 
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.
98  **/
99
100 static void g_simple_async_result_async_result_iface_init (GAsyncResultIface       *iface);
101
102 struct _GSimpleAsyncResult
103 {
104   GObject parent_instance;
105
106   GObject *source_object;
107   GAsyncReadyCallback callback;
108   gpointer user_data;
109   GError *error;
110   gboolean failed;
111   gboolean handle_cancellation;
112
113   gpointer source_tag;
114
115   union {
116     gpointer v_pointer;
117     gboolean v_boolean;
118     gssize   v_ssize;
119   } op_res;
120
121   GDestroyNotify destroy_op_res;
122 };
123
124 struct _GSimpleAsyncResultClass
125 {
126   GObjectClass parent_class;
127 };
128
129
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))
133
134 static void
135 g_simple_async_result_finalize (GObject *object)
136 {
137   GSimpleAsyncResult *simple;
138
139   simple = G_SIMPLE_ASYNC_RESULT (object);
140
141   if (simple->source_object)
142     g_object_unref (simple->source_object);
143
144   if (simple->destroy_op_res)
145     simple->destroy_op_res (simple->op_res.v_pointer);
146
147   if (simple->error)
148     g_error_free (simple->error);
149   
150   if (G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize)
151     (*G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize) (object);
152 }
153
154 static void
155 g_simple_async_result_class_init (GSimpleAsyncResultClass *klass)
156 {
157   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
158   
159   gobject_class->finalize = g_simple_async_result_finalize;
160 }
161
162 static void
163 g_simple_async_result_init (GSimpleAsyncResult *simple)
164 {
165   simple->handle_cancellation = TRUE;
166 }
167
168 /**
169  * g_simple_async_result_new:
170  * @source_object: a #GObject.
171  * @callback: a #GAsyncReadyCallback.
172  * @user_data: user data passed to @callback.
173  * @source_tag:
174  * 
175  * Creates a #GSimpleAsyncResult.
176  * 
177  * Returns: a #GSimpleAsyncResult.
178  **/
179 GSimpleAsyncResult *
180 g_simple_async_result_new (GObject *source_object,
181                            GAsyncReadyCallback callback,
182                            gpointer user_data,
183                            gpointer source_tag)
184 {
185   GSimpleAsyncResult *simple;
186
187   g_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
188
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;
194   
195   return simple;
196 }
197
198 /**
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.
204  * 
205  * Creates a #GSimpleAsyncResult from an error condition.
206  * 
207  * Returns: a #GSimpleAsyncResult.
208  **/
209 GSimpleAsyncResult *
210 g_simple_async_result_new_from_error (GObject *source_object,
211                                       GAsyncReadyCallback callback,
212                                       gpointer user_data,
213                                       GError *error)
214 {
215   GSimpleAsyncResult *simple;
216
217   g_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
218
219   simple = g_simple_async_result_new (source_object,
220                                       callback,
221                                       user_data, NULL);
222   g_simple_async_result_set_from_error (simple, error);
223
224   return simple;
225 }
226
227 /**
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.
236  * 
237  * Creates a new #GSimpleAsyncResult with a set error.
238  * 
239  * Returns: a #GSimpleAsyncResult.
240  **/
241 GSimpleAsyncResult *
242 g_simple_async_result_new_error (GObject *source_object,
243                                  GAsyncReadyCallback callback,
244                                  gpointer user_data,
245                                  GQuark         domain,
246                                  gint           code,
247                                  const char    *format,
248                                  ...)
249 {
250   GSimpleAsyncResult *simple;
251   va_list args;
252   
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);
256
257   simple = g_simple_async_result_new (source_object,
258                                       callback,
259                                       user_data, NULL);
260
261   va_start (args, format);
262   g_simple_async_result_set_error_va (simple, domain, code, format, args);
263   va_end (args);
264   
265   return simple;
266 }
267
268
269 static gpointer
270 g_simple_async_result_get_user_data (GAsyncResult *res)
271 {
272   return G_SIMPLE_ASYNC_RESULT (res)->user_data;
273 }
274
275 static GObject *
276 g_simple_async_result_get_source_object (GAsyncResult *res)
277 {
278   if (G_SIMPLE_ASYNC_RESULT (res)->source_object)
279     return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object);
280   return NULL;
281 }
282
283 static void
284 g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface)
285 {
286   iface->get_user_data = g_simple_async_result_get_user_data;
287   iface->get_source_object = g_simple_async_result_get_source_object;
288 }
289
290 /**
291  * g_simple_async_result_set_handle_cancellation:
292  * @simple: a #GSimpleAsyncResult.
293  * @handle_cancellation: a #gboolean.
294  * 
295  * Sets whether to handle cancellation within the asynchronous operation.
296  * 
297  **/
298 void
299 g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple,
300                                                gboolean handle_cancellation)
301 {
302   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
303   simple->handle_cancellation = handle_cancellation;
304 }
305
306 /**
307  * g_simple_async_result_get_source_tag:
308  * @simple: a #GSimpleAsyncResult.
309  * 
310  * Gets the source tag for the #GSimpleAsyncResult.
311  * 
312  * Returns: a #gpointer to the source object for the #GSimpleAsyncResult.
313  **/
314 gpointer
315 g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple)
316 {
317   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
318   return simple->source_tag;
319 }
320
321 /**
322  * g_simple_async_result_propagate_error:
323  * @simple: a #GSimpleAsyncResult.
324  * @dest: a location to propegate the error to.
325  * 
326  * Propegates an error from within the simple asynchronous result to
327  * a given destination.
328  * 
329  * Returns: %TRUE if the error was propegated to @dest. %FALSE otherwise.
330  **/
331 gboolean
332 g_simple_async_result_propagate_error (GSimpleAsyncResult *simple,
333                                        GError **dest)
334 {
335   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
336
337   if (simple->failed)
338     {
339       g_propagate_error (dest, simple->error);
340       simple->error = NULL;
341       return TRUE;
342     }
343   return FALSE;
344 }
345
346 /**
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.
351  * 
352  * Sets the operation result within the asynchronous result to a pointer.
353  **/
354 void
355 g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult      *simple,
356                                            gpointer                 op_res,
357                                            GDestroyNotify           destroy_op_res)
358 {
359   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
360
361   simple->op_res.v_pointer = op_res;
362   simple->destroy_op_res = destroy_op_res;
363 }
364
365 /**
366  * g_simple_async_result_get_op_res_gpointer:
367  * @simple: a #GSimpleAsyncResult.
368  * 
369  * Gets a pointer result as returned by the asynchronous function.
370  * 
371  * Returns: a pointer from the result.
372  **/
373 gpointer
374 g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult      *simple)
375 {
376   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
377   return simple->op_res.v_pointer;
378 }
379
380 /**
381  * g_simple_async_result_set_op_res_gssize:
382  * @simple: a #GSimpleAsyncResult.
383  * @op_res: a #gssize.
384  * 
385  * Sets the operation result within the asynchronous result to the given @op_res. 
386  **/
387 void
388 g_simple_async_result_set_op_res_gssize   (GSimpleAsyncResult      *simple,
389                                            gssize                   op_res)
390 {
391   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
392   simple->op_res.v_ssize = op_res;
393 }
394
395 /**
396  * g_simple_async_result_get_op_res_gssize:
397  * @simple: a #GSimpleAsyncResult.
398  * 
399  * Gets a gssize from the asynchronous result.
400  * 
401  * Returns: a gssize returned from the asynchronous function.
402  **/
403 gssize
404 g_simple_async_result_get_op_res_gssize   (GSimpleAsyncResult      *simple)
405 {
406   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0);
407   return simple->op_res.v_ssize;
408 }
409
410 /**
411  * g_simple_async_result_set_op_res_gboolean:
412  * @simple: a #GSimpleAsyncResult.
413  * @op_res: a #gboolean.
414  * 
415  * Sets the operation result to a boolean within the asynchronous result.
416  *  
417  **/
418 void
419 g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult      *simple,
420                                            gboolean                 op_res)
421 {
422   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
423   simple->op_res.v_boolean = !!op_res;
424 }
425
426 /**
427  * g_simple_async_result_get_op_res_gboolean:
428  * @simple: a #GSimpleAsyncResult.
429  * 
430  * Gets the operation result boolean from within the asynchronous result.
431  * 
432  * Returns: %TRUE if the operation's result was %TRUE, %FALSE if the operation's
433  * result was %FALSE. 
434  **/
435 gboolean
436 g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult      *simple)
437 {
438   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
439   return simple->op_res.v_boolean;
440 }
441
442 /**
443  * g_simple_async_result_set_from_error:
444  * @simple: a #GSimpleAsyncResult.
445  * @error: #GError.
446  * 
447  * Sets the result from a #GError. 
448  **/
449 void
450 g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
451                                       GError *error)
452 {
453   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
454   g_return_if_fail (error != NULL);
455
456   simple->error = g_error_copy (error);
457   simple->failed = TRUE;
458 }
459
460 static GError* 
461 _g_error_new_valist (GQuark         domain,
462                     gint           code,
463                     const char    *format,
464                     va_list        args)
465 {
466   GError *error;
467   char *message;
468
469   message = g_strdup_vprintf (format, args);
470
471   error = g_error_new_literal (domain, code, message);
472   g_free (message);
473   
474   return error;
475 }
476
477 /**
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. 
484  * 
485  * Sets an error within the asynchronous result without a #GError. Unless 
486  * writing a binding, see g_simple_async_result_set_error().
487  **/
488 void
489 g_simple_async_result_set_error_va (GSimpleAsyncResult *simple,
490                                     GQuark         domain,
491                                     gint           code,
492                                     const char    *format,
493                                     va_list        args)
494 {
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);
498
499   simple->error = _g_error_new_valist (domain, code, format, args);
500   simple->failed = TRUE;
501 }
502
503 /**
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.
510  * 
511  * Sets an error within the asynchronous result without a #GError.
512  * 
513  **/
514 void
515 g_simple_async_result_set_error (GSimpleAsyncResult *simple,
516                                  GQuark         domain,
517                                  gint           code,
518                                  const char    *format,
519                                  ...)
520 {
521   va_list args;
522
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);
526
527   va_start (args, format);
528   g_simple_async_result_set_error_va (simple, domain, code, format, args);
529   va_end (args);
530 }
531
532 /**
533  * g_simple_async_result_complete:
534  * @simple: a #GSimpleAsyncResult.
535  * 
536  * Completes an asynchronous I/O job.
537  * 
538  **/
539 void
540 g_simple_async_result_complete (GSimpleAsyncResult *simple)
541 {
542   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
543
544   if (simple->callback)
545     simple->callback (simple->source_object,
546                       G_ASYNC_RESULT (simple),
547                       simple->user_data);
548 }
549
550 static gboolean
551 complete_in_idle_cb (gpointer data)
552 {
553   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data);
554
555   g_simple_async_result_complete (simple);
556
557   return FALSE;
558 }
559
560 /**
561  * g_simple_async_result_complete_in_idle:
562  * @simple: a #GSimpleAsyncResult.
563  * 
564  * Completes an asynchronous function in the main event loop using 
565  * an idle function.
566  *  
567  **/
568 void
569 g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
570 {
571   GSource *source;
572   guint id;
573   
574   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
575   
576   g_object_ref (simple);
577   
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);
581
582   id = g_source_attach (source, NULL);
583   g_source_unref (source);
584 }
585
586 typedef struct {
587   GSimpleAsyncResult *simple;
588   GSimpleAsyncThreadFunc func;
589 } RunInThreadData;
590
591 static void
592 run_in_thread (GIOJob *job,
593                GCancellable *c,
594                gpointer _data)
595 {
596   RunInThreadData *data = _data;
597   GSimpleAsyncResult *simple = data->simple;
598
599   if (simple->handle_cancellation &&
600       g_cancellable_is_cancelled (c))
601     {
602        g_simple_async_result_set_error (simple,
603                                         G_IO_ERROR,
604                                         G_IO_ERROR_CANCELLED,
605                                        _("Operation was cancelled"));
606     }
607   else
608     {
609       data->func (simple,
610                   simple->source_object,
611                   c);
612     }
613
614   g_simple_async_result_complete_in_idle (data->simple);
615   g_object_unref (data->simple);
616   g_free (data);
617 }
618
619 /**
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. 
625  * 
626  * Runs the asynchronous job in a separated thread.
627  * 
628  **/
629 void
630 g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple,
631                                      GSimpleAsyncThreadFunc func,
632                                      int io_priority, 
633                                      GCancellable *cancellable)
634 {
635   RunInThreadData *data;
636   
637   g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
638   g_return_if_fail (func != NULL);
639
640   data = g_new (RunInThreadData, 1);
641   data->func = func;
642   data->simple = g_object_ref (simple);
643   g_schedule_io_job (run_in_thread, data, NULL, io_priority, cancellable);
644 }
645
646 /**
647  * g_simple_async_report_error_in_idle:
648  * @object:
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.
655  * 
656  * Reports an error in an idle function.
657  * 
658  **/
659 void
660 g_simple_async_report_error_in_idle (GObject *object,
661                                      GAsyncReadyCallback callback,
662                                      gpointer user_data,
663                                      GQuark         domain,
664                                      gint           code,
665                                      const char    *format,
666                                      ...)
667 {
668   GSimpleAsyncResult *simple;
669   va_list args;
670   
671   g_return_if_fail (G_IS_OBJECT (object));
672   g_return_if_fail (domain != 0);
673   g_return_if_fail (format != NULL);
674
675   simple = g_simple_async_result_new (object,
676                                       callback,
677                                       user_data, NULL);
678
679   va_start (args, format);
680   g_simple_async_result_set_error_va (simple, domain, code, format, args);
681   va_end (args);
682   g_simple_async_result_complete_in_idle (simple);
683   g_object_unref (simple);
684 }
685
686 #define __G_SIMPLE_ASYNC_RESULT_C__
687 #include "gioaliasdef.c"