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