[glib] gio: handle GSimpleAsyncResult errors in _finish vmethods



commit 538b2f106de78b7dfeac2a98f3d5594ed0ed2ade
Author: Dan Winship <danw gnome org>
Date:   Mon Jun 11 13:44:19 2012 -0400

    gio: handle GSimpleAsyncResult errors in _finish vmethods
    
    Originally, the standard idiom with GSimpleAsyncResult was to handle
    all errors in the _finish wrapper function, so that vmethods only had
    to deal with successful results. But this means that chaining up to a
    parent _finish vmethod won't work correctly. Fix this by also checking
    for errors in all the relevant vmethods. (We have to redundantly check
    in both the vmethod and the wrapper to preserve compatibility.)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=667375
    https://bugzilla.gnome.org/show_bug.cgi?id=661767

 gio/gasyncinitable.c       |   19 ++++++++-----------
 gio/gbufferedinputstream.c |    3 +++
 gio/gfile.c                |   42 +++++++++++++++++++++++++++++++++++++++++-
 gio/gfileenumerator.c      |    8 ++++++++
 gio/gfileinputstream.c     |    3 +++
 gio/gfileoutputstream.c    |    7 +++++--
 gio/ginputstream.c         |   12 ++++++++++++
 gio/giostream.c            |    5 +++++
 gio/gloadableicon.c        |    3 +++
 gio/goutputstream.c        |   16 ++++++++++++++++
 10 files changed, 104 insertions(+), 14 deletions(-)
---
diff --git a/gio/gasyncinitable.c b/gio/gasyncinitable.c
index 4d0c097..b13fac6 100644
--- a/gio/gasyncinitable.c
+++ b/gio/gasyncinitable.c
@@ -294,18 +294,15 @@ g_async_initable_real_init_finish (GAsyncInitable  *initable,
 				   GAsyncResult    *res,
 				   GError         **error)
 {
-  /* Although g_async_initable_init_finish() does this error handling
-   * as well, we do it here too, so that a class that reimplements
-   * GAsyncInitable can properly run its parent class's implementation
-   * by directly invoking its ->init_async() and ->init_finish().
-   */
-  if (G_IS_SIMPLE_ASYNC_RESULT (res))
-    {
-      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-      if (g_simple_async_result_propagate_error (simple, error))
-	return FALSE;
-    }
+  GSimpleAsyncResult *simple;
+
+  g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (initable),
+							g_async_initable_real_init_async),
+			FALSE);
 
+  simple = G_SIMPLE_ASYNC_RESULT (res);
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
   return TRUE;
 }
 
diff --git a/gio/gbufferedinputstream.c b/gio/gbufferedinputstream.c
index 166bd41..139199d 100644
--- a/gio/gbufferedinputstream.c
+++ b/gio/gbufferedinputstream.c
@@ -1131,6 +1131,9 @@ g_buffered_input_stream_real_fill_finish (GBufferedInputStream *stream,
   simple = G_SIMPLE_ASYNC_RESULT (result);
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_real_fill_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return -1;
+
   nread = g_simple_async_result_get_op_res_gssize (simple);
   return nread;
 }
diff --git a/gio/gfile.c b/gio/gfile.c
index 3e44e42..69f4100 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -4889,6 +4889,9 @@ g_file_real_query_info_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_info_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
   if (data->info)
     return g_object_ref (data->info);
@@ -4960,6 +4963,9 @@ g_file_real_query_filesystem_info_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_filesystem_info_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
   if (data->info)
     return g_object_ref (data->info);
@@ -5034,6 +5040,9 @@ g_file_real_enumerate_children_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_enumerate_children_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
   if (data->enumerator)
     return g_object_ref (data->enumerator);
@@ -5096,6 +5105,9 @@ g_file_real_read_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_read_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
   if (op)
     return g_object_ref (op);
@@ -5156,6 +5168,9 @@ g_file_real_append_to_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_append_to_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
   if (op)
     return g_object_ref (op);
@@ -5216,6 +5231,9 @@ g_file_real_create_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
   if (op)
     return g_object_ref (op);
@@ -5301,6 +5319,9 @@ g_file_real_replace_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
   if (data->stream)
     return g_object_ref (data->stream);
@@ -5363,6 +5384,9 @@ g_file_real_open_readwrite_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_open_readwrite_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
   if (op)
     return g_object_ref (op);
@@ -5434,6 +5458,9 @@ g_file_real_create_readwrite_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_readwrite_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
   if (op)
     return g_object_ref (op);
@@ -5519,6 +5546,9 @@ g_file_real_replace_readwrite_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_readwrite_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
   if (data->stream)
     return g_object_ref (data->stream);
@@ -5590,6 +5620,9 @@ g_file_real_set_display_name_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_display_name_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
   if (data->file)
     return g_object_ref (data->file);
@@ -5717,6 +5750,9 @@ g_file_real_find_enclosing_mount_finish (GFile         *file,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_find_enclosing_mount_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   mount = g_simple_async_result_get_op_res_gpointer (simple);
   return g_object_ref (mount);
 }
@@ -5840,7 +5876,11 @@ g_file_real_copy_finish (GFile        *file,
 			 GAsyncResult *res,
 			 GError      **error)
 {
-  /* Error handled in g_file_copy_finish() */
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
   return TRUE;
 }
 
diff --git a/gio/gfileenumerator.c b/gio/gfileenumerator.c
index 654c691..fa6863d 100644
--- a/gio/gfileenumerator.c
+++ b/gio/gfileenumerator.c
@@ -693,6 +693,9 @@ g_file_enumerator_real_next_files_finish (GFileEnumerator                *enumer
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == 
 	    g_file_enumerator_real_next_files_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
 
   res = op->files;
@@ -750,7 +753,12 @@ g_file_enumerator_real_close_finish (GFileEnumerator  *enumerator,
                                      GError          **error)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == 
 	    g_file_enumerator_real_close_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
   return TRUE;
 }
diff --git a/gio/gfileinputstream.c b/gio/gfileinputstream.c
index 6168543..86d6d36 100644
--- a/gio/gfileinputstream.c
+++ b/gio/gfileinputstream.c
@@ -456,6 +456,9 @@ g_file_input_stream_real_query_info_finish (GFileInputStream  *stream,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_input_stream_real_query_info_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
   if (data->info)
     return g_object_ref (data->info);
diff --git a/gio/gfileoutputstream.c b/gio/gfileoutputstream.c
index ce09eb8..2670e0e 100644
--- a/gio/gfileoutputstream.c
+++ b/gio/gfileoutputstream.c
@@ -551,14 +551,17 @@ g_file_output_stream_real_query_info_async (GFileOutputStream     *stream,
 
 static GFileInfo *
 g_file_output_stream_real_query_info_finish (GFileOutputStream     *stream,
-						GAsyncResult         *res,
-						GError              **error)
+					     GAsyncResult         *res,
+					     GError              **error)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
   QueryInfoAsyncData *data;
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_output_stream_real_query_info_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
   if (data->info)
     return g_object_ref (data->info);
diff --git a/gio/ginputstream.c b/gio/ginputstream.c
index 8c61285..960811f 100644
--- a/gio/ginputstream.c
+++ b/gio/ginputstream.c
@@ -1227,6 +1227,9 @@ g_input_stream_real_read_finish (GInputStream  *stream,
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == 
 	    g_input_stream_real_read_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return -1;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
 
   return op->count_read;
@@ -1378,6 +1381,10 @@ g_input_stream_real_skip_finish (GInputStream  *stream,
   SkipData *op;
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_input_stream_real_skip_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return -1;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
   return op->count_skipped;
 }
@@ -1434,6 +1441,11 @@ g_input_stream_real_close_finish (GInputStream  *stream,
 				  GError       **error)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_input_stream_real_close_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
   return TRUE;
 }
diff --git a/gio/giostream.c b/gio/giostream.c
index 593eeda..e318c4a 100644
--- a/gio/giostream.c
+++ b/gio/giostream.c
@@ -588,8 +588,13 @@ g_io_stream_real_close_finish (GIOStream     *stream,
 			       GError       **error)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) ==
 		  g_io_stream_real_close_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
   return TRUE;
 }
 
diff --git a/gio/gloadableicon.c b/gio/gloadableicon.c
index 441eb1b..66f9770 100644
--- a/gio/gloadableicon.c
+++ b/gio/gloadableicon.c
@@ -229,6 +229,9 @@ g_loadable_icon_real_load_finish (GLoadableIcon        *icon,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_loadable_icon_real_load_async);
 
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
 
   if (type)
diff --git a/gio/goutputstream.c b/gio/goutputstream.c
index 3ee4cf0..d512bbb 100644
--- a/gio/goutputstream.c
+++ b/gio/goutputstream.c
@@ -1546,6 +1546,10 @@ g_output_stream_real_write_finish (GOutputStream  *stream,
   WriteData *op;
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return -1;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
   return op->count_written;
 }
@@ -1613,6 +1617,10 @@ g_output_stream_real_splice_finish (GOutputStream  *stream,
   SpliceData *op;
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return -1;
+
   op = g_simple_async_result_get_op_res_gpointer (simple);
   return op->bytes_copied;
 }
@@ -1656,6 +1664,10 @@ g_output_stream_real_flush_finish (GOutputStream  *stream,
                                    GAsyncResult   *result,
                                    GError        **error)
 {
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
   return TRUE;
 }
 
@@ -1720,6 +1732,10 @@ g_output_stream_real_close_finish (GOutputStream  *stream,
                                    GError        **error)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
   return TRUE;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]