[glib/wip/task: 6/11] gio: port file/vfs-related classes from GSimpleAsyncResult to GTask



commit 849bbdb50833e9c1e5aefa9cfcd13dbf5cb16faa
Author: Dan Winship <danw gnome org>
Date:   Thu Aug 2 15:50:35 2012 -0400

    gio: port file/vfs-related classes from GSimpleAsyncResult to GTask
    
    NOTE: Needs maintainer sanity-checking before being merged to master.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=661767

 gio/gdrive.c            |   73 +++--
 gio/gfile.c             |  965 ++++++++++++++++++-----------------------------
 gio/gfileenumerator.c   |  184 ++++------
 gio/gfileicon.c         |   65 +---
 gio/gfileinputstream.c  |   78 ++---
 gio/gfileiostream.c     |   11 +-
 gio/gfileoutputstream.c |   98 ++---
 gio/gloadableicon.c     |   68 ++--
 gio/gmount.c            |  105 +++---
 gio/gunixmount.c        |  121 +++----
 gio/gunixvolume.c       |  103 +++---
 gio/gvolume.c           |   44 ++-
 12 files changed, 763 insertions(+), 1152 deletions(-)
---
diff --git a/gio/gdrive.c b/gio/gdrive.c
index 0e8c8ef..6a90838 100644
--- a/gio/gdrive.c
+++ b/gio/gdrive.c
@@ -23,7 +23,7 @@
 
 #include "config.h"
 #include "gdrive.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gasyncresult.h"
 #include "gioerror.h"
 #include "glibintl.h"
@@ -358,10 +358,13 @@ g_drive_eject (GDrive              *drive,
 
   if (iface->eject == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   _("drive doesn't implement eject"));
-      
+      GTask *task;
+
+      task = g_task_new (drive, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_drive_eject_with_operation);
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			       _("drive doesn't implement eject"));
+      g_object_unref (task);
       return;
     }
   
@@ -393,7 +396,9 @@ g_drive_eject_finish (GDrive        *drive,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
-
+  else if (g_async_result_is_tagged (result, g_drive_eject_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
+  
   iface = G_DRIVE_GET_IFACE (drive);
   
   return (* iface->eject_finish) (drive, result, error);
@@ -431,13 +436,16 @@ g_drive_eject_with_operation (GDrive              *drive,
 
   if (iface->eject == NULL && iface->eject_with_operation == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (drive),
-					   callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   /* Translators: This is an error
-					    * message for drive objects that
-					    * don't implement any of eject or eject_with_operation. */
-					   _("drive doesn't implement eject or eject_with_operation"));
+      GTask *task;
+
+      task = g_task_new (drive, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_drive_eject_with_operation);
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			       /* Translators: This is an error
+				* message for drive objects that
+				* don't implement any of eject or eject_with_operation. */
+			       _("drive doesn't implement eject or eject_with_operation"));
+      g_object_unref (task);
       return;
     }
 
@@ -473,6 +481,8 @@ g_drive_eject_with_operation_finish (GDrive        *drive,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_drive_eject_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_DRIVE_GET_IFACE (drive);
   if (iface->eject_with_operation_finish != NULL)
@@ -508,10 +518,13 @@ g_drive_poll_for_media (GDrive              *drive,
 
   if (iface->poll_for_media == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   _("drive doesn't implement polling for media"));
-      
+      GTask *task;
+
+      task = g_task_new (drive, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_drive_poll_for_media);
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			       _("drive doesn't implement polling for media"));
+      g_object_unref (task); 
       return;
     }
   
@@ -541,6 +554,8 @@ g_drive_poll_for_media_finish (GDrive        *drive,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_drive_poll_for_media))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_DRIVE_GET_IFACE (drive);
   
@@ -711,9 +726,13 @@ g_drive_start (GDrive              *drive,
 
   if (iface->start == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   _("drive doesn't implement start"));
+      GTask *task;
+
+      task = g_task_new (drive, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_drive_start);
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			       _("drive doesn't implement start"));
+      g_object_unref (task);
       return;
     }
 
@@ -745,6 +764,8 @@ g_drive_start_finish (GDrive         *drive,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_drive_start))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_DRIVE_GET_IFACE (drive);
 
@@ -810,9 +831,13 @@ g_drive_stop (GDrive               *drive,
 
   if (iface->stop == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   _("drive doesn't implement stop"));
+      GTask *task;
+
+      task = g_task_new (drive, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_drive_start);
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			       _("drive doesn't implement stop"));
+      g_object_unref (task);
       return;
     }
 
@@ -844,6 +869,8 @@ g_drive_stop_finish (GDrive        *drive,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_drive_start))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_DRIVE_GET_IFACE (drive);
 
diff --git a/gio/gfile.c b/gio/gfile.c
index eeb5424..8665f46 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -36,8 +36,7 @@
 #endif
 #include "gfile.h"
 #include "gvfs.h"
-#include "gioscheduler.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gfileattribute-priv.h"
 #include "gfiledescriptorbased.h"
 #include "gpollfilemonitor.h"
@@ -4299,12 +4298,10 @@ g_file_mount_mountable (GFile               *file,
 
   if (iface->mount_mountable == NULL) 
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (file),
-					   callback,
-					   user_data,
-					   G_IO_ERROR,
-					   G_IO_ERROR_NOT_SUPPORTED,
-					   _("Operation not supported"));
+      g_task_report_new_error (file, callback, user_data,
+                               g_file_mount_mountable,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
   
@@ -4342,6 +4339,8 @@ g_file_mount_mountable_finish (GFile         *file,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return NULL;
+  else if (g_async_result_is_tagged (result, g_file_mount_mountable))
+    return g_task_propagate_pointer (G_TASK (result), error);
   
   iface = G_FILE_GET_IFACE (file);
   return (* iface->mount_mountable_finish) (file, result, error);
@@ -4381,12 +4380,10 @@ g_file_unmount_mountable (GFile               *file,
   
   if (iface->unmount_mountable == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (file),
-					   callback,
-					   user_data,
-					   G_IO_ERROR,
-					   G_IO_ERROR_NOT_SUPPORTED,
-					   _("Operation not supported"));
+      g_task_report_new_error (file, callback, user_data,
+                               g_file_unmount_mountable_with_operation,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
   
@@ -4425,6 +4422,8 @@ g_file_unmount_mountable_finish (GFile         *file,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_unmount_mountable_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
   
   iface = G_FILE_GET_IFACE (file);
   return (* iface->unmount_mountable_finish) (file, result, error);
@@ -4466,12 +4465,10 @@ g_file_unmount_mountable_with_operation (GFile               *file,
 
   if (iface->unmount_mountable == NULL && iface->unmount_mountable_with_operation == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (file),
-					   callback,
-					   user_data,
-					   G_IO_ERROR,
-					   G_IO_ERROR_NOT_SUPPORTED,
-					   _("Operation not supported"));
+      g_task_report_new_error (file, callback, user_data,
+                               g_file_unmount_mountable_with_operation,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
 
@@ -4518,6 +4515,8 @@ g_file_unmount_mountable_with_operation_finish (GFile         *file,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_unmount_mountable_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_FILE_GET_IFACE (file);
   if (iface->unmount_mountable_with_operation_finish != NULL)
@@ -4560,12 +4559,10 @@ g_file_eject_mountable (GFile               *file,
   
   if (iface->eject_mountable == NULL) 
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (file),
-					   callback,
-					   user_data,
-					   G_IO_ERROR,
-					   G_IO_ERROR_NOT_SUPPORTED,
-					   _("Operation not supported"));
+      g_task_report_new_error (file, callback, user_data,
+                               g_file_eject_mountable_with_operation,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
   
@@ -4602,6 +4599,8 @@ g_file_eject_mountable_finish (GFile         *file,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_eject_mountable_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_FILE_GET_IFACE (file);
   return (* iface->eject_mountable_finish) (file, result, error);
@@ -4643,12 +4642,10 @@ g_file_eject_mountable_with_operation (GFile               *file,
 
   if (iface->eject_mountable == NULL && iface->eject_mountable_with_operation == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (file),
-					   callback,
-					   user_data,
-					   G_IO_ERROR,
-					   G_IO_ERROR_NOT_SUPPORTED,
-					   _("Operation not supported"));
+      g_task_report_new_error (file, callback, user_data,
+                               g_file_eject_mountable_with_operation,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
 
@@ -4693,6 +4690,8 @@ g_file_eject_mountable_with_operation_finish (GFile         *file,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_eject_mountable_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_FILE_GET_IFACE (file);
   if (iface->eject_mountable_with_operation_finish != NULL)
@@ -4828,35 +4827,30 @@ g_file_monitor (GFile             *file,
 typedef struct {
   char *attributes;
   GFileQueryInfoFlags flags;
-  GFileInfo *info;
 } QueryInfoAsyncData;
 
 static void
 query_info_data_free (QueryInfoAsyncData *data)
 {
-  if (data->info)
-    g_object_unref (data->info);
   g_free (data->attributes);
-  g_free (data);
+  g_slice_free (QueryInfoAsyncData, data);
 }
 
 static void
-query_info_async_thread (GSimpleAsyncResult *res,
-			 GObject            *object,
-			 GCancellable       *cancellable)
+query_info_async_thread (GTask         *task,
+                         gpointer       object,
+                         gpointer       task_data,
+			 GCancellable  *cancellable)
 {
-  GError *error = NULL;
-  QueryInfoAsyncData *data;
+  QueryInfoAsyncData *data = task_data;
   GFileInfo *info;
-  
-  data = g_simple_async_result_get_op_res_gpointer (res);
-  
-  info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
+  GError *error = NULL;
 
-  if (info == NULL)
-    g_simple_async_result_take_error (res, error);
+  info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
+  if (info)
+    g_task_return_pointer (task, info, g_object_unref);
   else
-    data->info = info;
+    g_task_return_error (task, error);
 }
 
 static void
@@ -4868,18 +4862,18 @@ g_file_real_query_info_async (GFile               *file,
 			      GAsyncReadyCallback  callback,
 			      gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   QueryInfoAsyncData *data;
 
-  data = g_new0 (QueryInfoAsyncData, 1);
+  data = g_slice_new (QueryInfoAsyncData);
   data->attributes = g_strdup (attributes);
   data->flags = flags;
   
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_info_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
-  
-  g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify)query_info_data_free);
+  g_task_set_priority (task, io_priority);
+  g_task_run_in_thread (task, query_info_async_thread);
+  g_object_unref (task);
 }
 
 static GFileInfo *
@@ -4887,52 +4881,26 @@ g_file_real_query_info_finish (GFile         *file,
 			       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_real_query_info_async);
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  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);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
-typedef struct {
-  char *attributes;
-  GFileInfo *info;
-} QueryFilesystemInfoAsyncData;
-
 static void
-query_filesystem_info_data_free (QueryFilesystemInfoAsyncData *data)
+query_filesystem_info_async_thread (GTask         *task,
+                                    gpointer       object,
+                                    gpointer       task_data,
+                                    GCancellable  *cancellable)
 {
-  if (data->info)
-    g_object_unref (data->info);
-  g_free (data->attributes);
-  g_free (data);
-}
-
-static void
-query_filesystem_info_async_thread (GSimpleAsyncResult *res,
-                                    GObject            *object,
-                                    GCancellable       *cancellable)
-{
-  GError *error = NULL;
-  QueryFilesystemInfoAsyncData *data;
+  const char *attributes = task_data;
   GFileInfo *info;
+  GError *error = NULL;
   
-  data = g_simple_async_result_get_op_res_gpointer (res);
-  
-  info = g_file_query_filesystem_info (G_FILE (object), data->attributes, cancellable, &error);
-
-  if (info == NULL)
-    g_simple_async_result_take_error (res, error);
+  info = g_file_query_filesystem_info (G_FILE (object), attributes, cancellable, &error);
+  if (info)
+    g_task_return_pointer (task, info, g_object_unref);
   else
-    data->info = info;
+    g_task_return_error (task, error);
 }
 
 static void
@@ -4943,17 +4911,13 @@ g_file_real_query_filesystem_info_async (GFile               *file,
                                          GAsyncReadyCallback  callback,
                                          gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  QueryFilesystemInfoAsyncData *data;
+  GTask *task;
 
-  data = g_new0 (QueryFilesystemInfoAsyncData, 1);
-  data->attributes = g_strdup (attributes);
-  
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_filesystem_info_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_filesystem_info_data_free);
-  
-  g_simple_async_result_run_in_thread (res, query_filesystem_info_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_strdup (attributes), g_free);
+  g_task_set_priority (task, io_priority);
+  g_task_run_in_thread (task, query_filesystem_info_async_thread);
+  g_object_unref (task);
 }
 
 static GFileInfo *
@@ -4961,53 +4925,26 @@ g_file_real_query_filesystem_info_finish (GFile         *file,
                                           GAsyncResult  *res,
                                           GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  QueryFilesystemInfoAsyncData *data;
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  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);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
-typedef struct {
-  char *attributes;
-  GFileQueryInfoFlags flags;
-  GFileEnumerator *enumerator;
-} EnumerateChildrenAsyncData;
-
 static void
-enumerate_children_data_free (EnumerateChildrenAsyncData *data)
+enumerate_children_async_thread (GTask         *task,
+                                 gpointer       object,
+                                 gpointer       task_data,
+                                 GCancellable  *cancellable)
 {
-  if (data->enumerator)
-    g_object_unref (data->enumerator);
-  g_free (data->attributes);
-  g_free (data);
-}
-
-static void
-enumerate_children_async_thread (GSimpleAsyncResult *res,
-				 GObject            *object,
-				 GCancellable       *cancellable)
-{
-  GError *error = NULL;
-  EnumerateChildrenAsyncData *data;
+  QueryInfoAsyncData *data = task_data;
   GFileEnumerator *enumerator;
-  
-  data = g_simple_async_result_get_op_res_gpointer (res);
-  
-  enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
+  GError *error = NULL;
 
-  if (enumerator == NULL)
-    g_simple_async_result_take_error (res, error);
+  enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
+  if (error)
+    g_task_return_error (task, error);
   else
-    data->enumerator = enumerator;
+    g_task_return_pointer (task, enumerator, g_object_unref);
 }
 
 static void
@@ -5019,18 +4956,18 @@ g_file_real_enumerate_children_async (GFile               *file,
 				      GAsyncReadyCallback  callback,
 				      gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  EnumerateChildrenAsyncData *data;
+  GTask *task;
+  QueryInfoAsyncData *data;
 
-  data = g_new0 (EnumerateChildrenAsyncData, 1);
+  data = g_slice_new (QueryInfoAsyncData);
   data->attributes = g_strdup (attributes);
   data->flags = flags;
-  
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_enumerate_children_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)enumerate_children_data_free);
-  
-  g_simple_async_result_run_in_thread (res, enumerate_children_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify)query_info_data_free);
+  g_task_set_priority (task, io_priority);
+  g_task_run_in_thread (task, enumerate_children_async_thread);
+  g_object_unref (task);
 }
 
 static GFileEnumerator *
@@ -5038,25 +4975,16 @@ g_file_real_enumerate_children_finish (GFile         *file,
 				       GAsyncResult  *res,
 				       GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  EnumerateChildrenAsyncData *data;
-
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_enumerate_children_async);
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  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);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 static void
-open_read_async_thread (GSimpleAsyncResult *res,
-			GObject            *object,
-			GCancellable       *cancellable)
+open_read_async_thread (GTask         *task,
+                        gpointer       object,
+                        gpointer       task_data,
+                        GCancellable  *cancellable)
 {
   GFileIface *iface;
   GFileInputStream *stream;
@@ -5066,21 +4994,17 @@ open_read_async_thread (GSimpleAsyncResult *res,
 
   if (iface->read_fn == NULL)
     {
-      g_set_error_literal (&error, G_IO_ERROR,
-                           G_IO_ERROR_NOT_SUPPORTED,
-                           _("Operation not supported"));
-
-      g_simple_async_result_take_error (res, error);
-
+      g_task_return_new_error (task, G_IO_ERROR,
+                               G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
   
   stream = iface->read_fn (G_FILE (object), cancellable, &error);
-
-  if (stream == NULL)
-    g_simple_async_result_take_error (res, error);
+  if (stream)
+    g_task_return_pointer (task, stream, g_object_unref);
   else
-    g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
+    g_task_return_error (task, error);
 }
 
 static void
@@ -5090,12 +5014,12 @@ g_file_real_read_async (GFile               *file,
 			GAsyncReadyCallback  callback,
 			gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_read_async);
-  
-  g_simple_async_result_run_in_thread (res, open_read_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  GTask *task;
+
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_priority (task, io_priority);
+  g_task_run_in_thread (task, open_read_async_thread);
+  g_object_unref (task);
 }
 
 static GFileInputStream *
@@ -5103,41 +5027,29 @@ g_file_real_read_finish (GFile         *file,
 			 GAsyncResult  *res,
 			 GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  gpointer op;
-
-  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;
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  op = g_simple_async_result_get_op_res_gpointer (simple);
-  if (op)
-    return g_object_ref (op);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 static void
-append_to_async_thread (GSimpleAsyncResult *res,
-			GObject            *object,
-			GCancellable       *cancellable)
+append_to_async_thread (GTask         *task,
+                        gpointer       source_object,
+                        gpointer       task_data,
+			GCancellable  *cancellable)
 {
   GFileIface *iface;
-  GFileCreateFlags *data;
+  GFileCreateFlags *data = task_data;
   GFileOutputStream *stream;
   GError *error = NULL;
 
-  iface = G_FILE_GET_IFACE (object);
-
-  data = g_simple_async_result_get_op_res_gpointer (res);
-
-  stream = iface->append_to (G_FILE (object), *data, cancellable, &error);
+  iface = G_FILE_GET_IFACE (source_object);
 
-  if (stream == NULL)
-    g_simple_async_result_take_error (res, error);
+  stream = iface->append_to (G_FILE (source_object), *data, cancellable, &error);
+  if (stream)
+    g_task_return_pointer (task, stream, g_object_unref);
   else
-    g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
+    g_task_return_error (task, error);
 }
 
 static void
@@ -5149,16 +5061,17 @@ g_file_real_append_to_async (GFile               *file,
 			     gpointer             user_data)
 {
   GFileCreateFlags *data;
-  GSimpleAsyncResult *res;
+  GTask *task;
 
   data = g_new0 (GFileCreateFlags, 1);
   *data = flags;
 
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_append_to_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, g_free);
+  g_task_set_priority (task, io_priority);
 
-  g_simple_async_result_run_in_thread (res, append_to_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, append_to_async_thread);
+  g_object_unref (task);
 }
 
 static GFileOutputStream *
@@ -5166,41 +5079,29 @@ g_file_real_append_to_finish (GFile         *file,
 			      GAsyncResult  *res,
 			      GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  gpointer op;
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  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);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 static void
-create_async_thread (GSimpleAsyncResult *res,
-		     GObject            *object,
-		     GCancellable       *cancellable)
+create_async_thread (GTask         *task,
+                     gpointer       source_object,
+                     gpointer       task_data,
+                     GCancellable  *cancellable)
 {
   GFileIface *iface;
-  GFileCreateFlags *data;
+  GFileCreateFlags *data = task_data;
   GFileOutputStream *stream;
   GError *error = NULL;
 
-  iface = G_FILE_GET_IFACE (object);
-
-  data = g_simple_async_result_get_op_res_gpointer (res);
-
-  stream = iface->create (G_FILE (object), *data, cancellable, &error);
+  iface = G_FILE_GET_IFACE (source_object);
 
-  if (stream == NULL)
-    g_simple_async_result_take_error (res, error);
+  stream = iface->create (G_FILE (source_object), *data, cancellable, &error);
+  if (stream)
+    g_task_return_pointer (task, stream, g_object_unref);
   else
-    g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
+    g_task_return_error (task, error);
 }
 
 static void
@@ -5212,16 +5113,17 @@ g_file_real_create_async (GFile               *file,
 			  gpointer             user_data)
 {
   GFileCreateFlags *data;
-  GSimpleAsyncResult *res;
+  GTask *task;
 
   data = g_new0 (GFileCreateFlags, 1);
   *data = flags;
 
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, g_free);
+  g_task_set_priority (task, io_priority);
 
-  g_simple_async_result_run_in_thread (res, create_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, create_async_thread);
+  g_object_unref (task);
 }
 
 static GFileOutputStream *
@@ -5229,19 +5131,9 @@ g_file_real_create_finish (GFile         *file,
 			   GAsyncResult  *res,
 			   GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  gpointer op;
-
-  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;
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  op = g_simple_async_result_get_op_res_gpointer (simple);
-  if (op)
-    return g_object_ref (op);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 typedef struct {
@@ -5261,30 +5153,29 @@ replace_async_data_free (ReplaceAsyncData *data)
 }
 
 static void
-replace_async_thread (GSimpleAsyncResult *res,
-		      GObject            *object,
-		      GCancellable       *cancellable)
+replace_async_thread (GTask         *task,
+                      gpointer       source_object,
+                      gpointer       task_data,
+		      GCancellable  *cancellable)
 {
   GFileIface *iface;
   GFileOutputStream *stream;
+  ReplaceAsyncData *data = task_data;
   GError *error = NULL;
-  ReplaceAsyncData *data;
 
-  iface = G_FILE_GET_IFACE (object);
+  iface = G_FILE_GET_IFACE (source_object);
   
-  data = g_simple_async_result_get_op_res_gpointer (res);
-
-  stream = iface->replace (G_FILE (object),
+  stream = iface->replace (G_FILE (source_object),
 			   data->etag,
 			   data->make_backup,
 			   data->flags,
 			   cancellable,
 			   &error);
 
-  if (stream == NULL)
-    g_simple_async_result_take_error (res, error);
+  if (stream)
+    g_task_return_pointer (task, stream, g_object_unref);
   else
-    data->stream = stream;
+    g_task_return_error (task, error);
 }
 
 static void
@@ -5297,7 +5188,7 @@ g_file_real_replace_async (GFile               *file,
 			   GAsyncReadyCallback  callback,
 			   gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   ReplaceAsyncData *data;
 
   data = g_new0 (ReplaceAsyncData, 1);
@@ -5305,11 +5196,12 @@ g_file_real_replace_async (GFile               *file,
   data->make_backup = make_backup;
   data->flags = flags;
 
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_async_data_free);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify)replace_async_data_free);
+  g_task_set_priority (task, io_priority);
 
-  g_simple_async_result_run_in_thread (res, replace_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, replace_async_thread);
+  g_object_unref (task);
 }
 
 static GFileOutputStream *
@@ -5317,35 +5209,29 @@ g_file_real_replace_finish (GFile         *file,
 			    GAsyncResult  *res,
 			    GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  ReplaceAsyncData *data;
-
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_async);
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  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);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 static void
-delete_async_thread (GSimpleAsyncResult *res,
-                     GObject            *object,
-                     GCancellable       *cancellable)
+delete_async_thread (GTask        *task,
+                     gpointer      object,
+                     gpointer      task_data,
+                     GCancellable *cancellable)
 {
+  GFile *file = object;
   GFileIface *iface;
   GError *error = NULL;
 
   iface = G_FILE_GET_IFACE (object);
 
-  if (!iface->delete_file (G_FILE (object),
-                           cancellable,
-                           &error))
-    g_simple_async_result_take_error (res, error);
+  if (iface->delete_file (file,
+                          cancellable,
+                          &error))
+    g_task_return_boolean (task, TRUE);
+  else
+    g_task_return_error (task, error);
 }
 
 static void
@@ -5355,11 +5241,12 @@ g_file_real_delete_async (GFile               *file,
                           GAsyncReadyCallback  callback,
                           gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
 
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_delete_async);
-  g_simple_async_result_run_in_thread (res, delete_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_priority (task, io_priority);
+  g_task_run_in_thread (task, delete_async_thread);
+  g_object_unref (task);
 }
 
 static gboolean
@@ -5367,20 +5254,16 @@ g_file_real_delete_finish (GFile         *file,
                            GAsyncResult  *res,
                            GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
 
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_delete_async);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return FALSE;
-
-  return TRUE;
+  return g_task_propagate_boolean (G_TASK (res), error);
 }
 
 static void
-open_readwrite_async_thread (GSimpleAsyncResult *res,
-			     GObject            *object,
-			     GCancellable       *cancellable)
+open_readwrite_async_thread (GTask        *task,
+                             gpointer      object,
+                             gpointer      task_data,
+			     GCancellable *cancellable)
 {
   GFileIface *iface;
   GFileIOStream *stream;
@@ -5390,21 +5273,17 @@ open_readwrite_async_thread (GSimpleAsyncResult *res,
 
   if (iface->open_readwrite == NULL)
     {
-      g_set_error_literal (&error, G_IO_ERROR,
-                           G_IO_ERROR_NOT_SUPPORTED,
-                           _("Operation not supported"));
-
-      g_simple_async_result_take_error (res, error);
-
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
 
   stream = iface->open_readwrite (G_FILE (object), cancellable, &error);
 
   if (stream == NULL)
-    g_simple_async_result_take_error (res, error);
+    g_task_return_error (task, error);
   else
-    g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
+    g_task_return_pointer (task, stream, g_object_unref);
 }
 
 static void
@@ -5414,12 +5293,13 @@ g_file_real_open_readwrite_async (GFile               *file,
 				  GAsyncReadyCallback  callback,
 				  gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
 
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_open_readwrite_async);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_priority (task, io_priority);
 
-  g_simple_async_result_run_in_thread (res, open_readwrite_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, open_readwrite_async_thread);
+  g_object_unref (task);
 }
 
 static GFileIOStream *
@@ -5427,52 +5307,37 @@ g_file_real_open_readwrite_finish (GFile         *file,
 				   GAsyncResult  *res,
 				   GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  gpointer op;
-
-  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);
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 static void
-create_readwrite_async_thread (GSimpleAsyncResult *res,
-			       GObject            *object,
-			       GCancellable       *cancellable)
+create_readwrite_async_thread (GTask        *task,
+                               gpointer      object,
+                               gpointer      task_data,
+			       GCancellable *cancellable)
 {
   GFileIface *iface;
-  GFileCreateFlags *data;
+  GFileCreateFlags *data = task_data;
   GFileIOStream *stream;
   GError *error = NULL;
 
   iface = G_FILE_GET_IFACE (object);
 
-  data = g_simple_async_result_get_op_res_gpointer (res);
-
   if (iface->create_readwrite == NULL)
     {
-      g_set_error_literal (&error, G_IO_ERROR,
-                           G_IO_ERROR_NOT_SUPPORTED,
-                           _("Operation not supported"));
-
-      g_simple_async_result_take_error (res, error);
-
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
 
   stream = iface->create_readwrite (G_FILE (object), *data, cancellable, &error);
 
   if (stream == NULL)
-    g_simple_async_result_take_error (res, error);
+    g_task_return_error (task, error);
   else
-    g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
+    g_task_return_pointer (task, stream, g_object_unref);
 }
 
 static void
@@ -5484,16 +5349,17 @@ g_file_real_create_readwrite_async (GFile               *file,
 				    gpointer             user_data)
 {
   GFileCreateFlags *data;
-  GSimpleAsyncResult *res;
+  GTask *task;
 
   data = g_new0 (GFileCreateFlags, 1);
   *data = flags;
 
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_readwrite_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, g_free);
+  g_task_set_priority (task, io_priority);
 
-  g_simple_async_result_run_in_thread (res, create_readwrite_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, create_readwrite_async_thread);
+  g_object_unref (task);
 }
 
 static GFileIOStream *
@@ -5501,23 +5367,12 @@ g_file_real_create_readwrite_finish (GFile         *file,
                                      GAsyncResult  *res,
                                      GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  gpointer op;
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  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);
-
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 typedef struct {
-  GFileIOStream *stream;
   char *etag;
   gboolean make_backup;
   GFileCreateFlags flags;
@@ -5526,26 +5381,23 @@ typedef struct {
 static void
 replace_rw_async_data_free (ReplaceRWAsyncData *data)
 {
-  if (data->stream)
-    g_object_unref (data->stream);
   g_free (data->etag);
-  g_free (data);
+  g_slice_free (ReplaceRWAsyncData, data);
 }
 
 static void
-replace_readwrite_async_thread (GSimpleAsyncResult *res,
-				GObject            *object,
-				GCancellable       *cancellable)
+replace_readwrite_async_thread (GTask        *task,
+                                gpointer      object,
+                                gpointer      task_data,
+				GCancellable *cancellable)
 {
   GFileIface *iface;
   GFileIOStream *stream;
   GError *error = NULL;
-  ReplaceRWAsyncData *data;
+  ReplaceRWAsyncData *data = task_data;
 
   iface = G_FILE_GET_IFACE (object);
 
-  data = g_simple_async_result_get_op_res_gpointer (res);
-
   stream = iface->replace_readwrite (G_FILE (object),
 				     data->etag,
 				     data->make_backup,
@@ -5554,9 +5406,9 @@ replace_readwrite_async_thread (GSimpleAsyncResult *res,
 				     &error);
 
   if (stream == NULL)
-    g_simple_async_result_take_error (res, error);
+    g_task_return_error (task, error);
   else
-    data->stream = stream;
+    g_task_return_pointer (task, stream, g_object_unref);
 }
 
 static void
@@ -5569,19 +5421,20 @@ g_file_real_replace_readwrite_async (GFile               *file,
 				     GAsyncReadyCallback  callback,
 				     gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   ReplaceRWAsyncData *data;
 
-  data = g_new0 (ReplaceRWAsyncData, 1);
+  data = g_slice_new0 (ReplaceRWAsyncData);
   data->etag = g_strdup (etag);
   data->make_backup = make_backup;
   data->flags = flags;
 
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_readwrite_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_rw_async_data_free);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify)replace_rw_async_data_free);
+  g_task_set_priority (task, io_priority);
 
-  g_simple_async_result_run_in_thread (res, replace_readwrite_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, replace_readwrite_async_thread);
+  g_object_unref (task);
 }
 
 static GFileIOStream *
@@ -5589,52 +5442,27 @@ g_file_real_replace_readwrite_finish (GFile         *file,
                                       GAsyncResult  *res,
                                       GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  ReplaceRWAsyncData *data;
-
-  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);
-
-  return NULL;
-}
-
-typedef struct {
-  char *name;
-  GFile *file;
-} SetDisplayNameAsyncData;
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-static void
-set_display_name_data_free (SetDisplayNameAsyncData *data)
-{
-  g_free (data->name);
-  if (data->file)
-    g_object_unref (data->file);
-  g_free (data);
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 static void
-set_display_name_async_thread (GSimpleAsyncResult *res,
-			       GObject            *object,
-			       GCancellable       *cancellable)
+set_display_name_async_thread (GTask        *task,
+                               gpointer      object,
+                               gpointer      task_data,
+			       GCancellable *cancellable)
 {
   GError *error = NULL;
-  SetDisplayNameAsyncData *data;
+  char *name = task_data;
   GFile *file;
   
-  data = g_simple_async_result_get_op_res_gpointer (res);
-  
-  file = g_file_set_display_name (G_FILE (object), data->name, cancellable, &error);
+  file = g_file_set_display_name (G_FILE (object), name, cancellable, &error);
 
   if (file == NULL)
-    g_simple_async_result_take_error (res, error);
+    g_task_return_error (task, error);
   else
-    data->file = file;
+    g_task_return_pointer (task, file, g_object_unref);
 }
 
 static void
@@ -5645,17 +5473,14 @@ g_file_real_set_display_name_async (GFile               *file,
 				    GAsyncReadyCallback  callback,
 				    gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  SetDisplayNameAsyncData *data;
+  GTask *task;
 
-  data = g_new0 (SetDisplayNameAsyncData, 1);
-  data->name = g_strdup (display_name);
-  
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_display_name_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_display_name_data_free);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_strdup (display_name), g_free);
+  g_task_set_priority (task, io_priority);
   
-  g_simple_async_result_run_in_thread (res, set_display_name_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, set_display_name_async_thread);
+  g_object_unref (task);
 }
 
 static GFile *
@@ -5663,19 +5488,9 @@ g_file_real_set_display_name_finish (GFile         *file,
 				     GAsyncResult  *res,
 				     GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  SetDisplayNameAsyncData *data;
-
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_display_name_async);
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  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);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 typedef struct {
@@ -5692,17 +5507,16 @@ set_info_data_free (SetInfoAsyncData *data)
     g_object_unref (data->info);
   if (data->error)
     g_error_free (data->error);
-  g_free (data);
+  g_slice_free (SetInfoAsyncData, data);
 }
 
 static void
-set_info_async_thread (GSimpleAsyncResult *res,
-		       GObject            *object,
-		       GCancellable       *cancellable)
+set_info_async_thread (GTask        *task,
+                       gpointer      object,
+                       gpointer      task_data,
+		       GCancellable *cancellable)
 {
-  SetInfoAsyncData *data;
-  
-  data = g_simple_async_result_get_op_res_gpointer (res);
+  SetInfoAsyncData *data = task_data;
   
   data->error = NULL;
   data->res = g_file_set_attributes_from_info (G_FILE (object),
@@ -5721,18 +5535,19 @@ g_file_real_set_attributes_async (GFile               *file,
 				  GAsyncReadyCallback  callback,
 				  gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   SetInfoAsyncData *data;
 
   data = g_new0 (SetInfoAsyncData, 1);
   data->info = g_file_info_dup (info);
   data->flags = flags;
   
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_attributes_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_info_data_free);
-  
-  g_simple_async_result_run_in_thread (res, set_info_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify)set_info_data_free);
+  g_task_set_priority (task, io_priority);
+
+  g_task_run_in_thread (task, set_info_async_thread);
+  g_object_unref (task);
 }
 
 static gboolean
@@ -5741,12 +5556,11 @@ g_file_real_set_attributes_finish (GFile         *file,
 				   GFileInfo    **info,
 				   GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
   SetInfoAsyncData *data;
   
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_attributes_async);
+  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
 
-  data = g_simple_async_result_get_op_res_gpointer (simple);
+  data = g_task_get_task_data (G_TASK (res));
 
   if (info) 
     *info = g_object_ref (data->info);
@@ -5758,9 +5572,10 @@ g_file_real_set_attributes_finish (GFile         *file,
 }
 
 static void
-find_enclosing_mount_async_thread (GSimpleAsyncResult *res,
-				    GObject            *object,
-				    GCancellable       *cancellable)
+find_enclosing_mount_async_thread (GTask        *task,
+                                   gpointer      object,
+                                   gpointer      task_data,
+                                   GCancellable *cancellable)
 {
   GError *error = NULL;
   GMount *mount;
@@ -5768,9 +5583,9 @@ find_enclosing_mount_async_thread (GSimpleAsyncResult *res,
   mount = g_file_find_enclosing_mount (G_FILE (object), cancellable, &error);
 
   if (mount == NULL)
-    g_simple_async_result_take_error (res, error);
+    g_task_return_error (task, error);
   else
-    g_simple_async_result_set_op_res_gpointer (res, mount, (GDestroyNotify)g_object_unref);
+    g_task_return_pointer (task, mount, g_object_unref);
 }
 
 static void
@@ -5780,29 +5595,23 @@ g_file_real_find_enclosing_mount_async (GFile               *file,
 					GAsyncReadyCallback  callback,
 					gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   
-  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_find_enclosing_mount_async);
+  task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_priority (task, io_priority);
   
-  g_simple_async_result_run_in_thread (res, find_enclosing_mount_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, find_enclosing_mount_async_thread);
+  g_object_unref (task);
 }
 
 static GMount *
 g_file_real_find_enclosing_mount_finish (GFile         *file,
-					  GAsyncResult  *res,
-					  GError       **error)
+                                         GAsyncResult  *res,
+                                         GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  GMount *mount;
-
-  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;
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  mount = g_simple_async_result_get_op_res_gpointer (simple);
-  return g_object_ref (mount);
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 
@@ -5918,6 +5727,8 @@ g_file_real_copy_finish (GFile        *file,
 			 GAsyncResult *res,
 			 GError      **error)
 {
+  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
+
   return g_task_propagate_boolean (G_TASK (res), error);
 }
 
@@ -6133,11 +5944,10 @@ g_file_mount_enclosing_volume (GFile               *location,
 
   if (iface->mount_enclosing_volume == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (location),
-					   callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   _("volume doesn't implement mount"));
-      
+      g_task_report_new_error (location, callback, user_data,
+                               g_file_mount_enclosing_volume,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("volume doesn't implement mount"));
       return;
     }
   
@@ -6169,6 +5979,8 @@ g_file_mount_enclosing_volume_finish (GFile         *location,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_mount_enclosing_volume))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_FILE_GET_IFACE (location);
 
@@ -6346,12 +6158,8 @@ g_file_load_contents (GFile         *file,
 }
 
 typedef struct {
-  GFile *file;
-  GError *error;
-  GCancellable *cancellable;
+  GTask *task;
   GFileReadMoreCallback read_more_callback;
-  GAsyncReadyCallback callback;
-  gpointer user_data;
   GByteArray *content;
   gsize pos;
   char *etag;
@@ -6361,15 +6169,10 @@ typedef struct {
 static void
 load_contents_data_free (LoadContentsData *data)
 {
-  if (data->error)
-    g_error_free (data->error);
-  if (data->cancellable)
-    g_object_unref (data->cancellable);
   if (data->content)
     g_byte_array_free (data->content, TRUE);
   g_free (data->etag);
-  g_object_unref (data->file);
-  g_free (data);
+  g_slice_free (LoadContentsData, data);
 }
 
 static void
@@ -6379,19 +6182,13 @@ load_contents_close_callback (GObject      *obj,
 {
   GInputStream *stream = G_INPUT_STREAM (obj);
   LoadContentsData *data = user_data;
-  GSimpleAsyncResult *res;
 
   /* Ignore errors here, we're only reading anyway */
   g_input_stream_close_finish (stream, close_res, NULL);
   g_object_unref (stream);
 
-  res = g_simple_async_result_new (G_OBJECT (data->file),
-				   data->callback,
-				   data->user_data,
-				   g_file_load_contents_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)load_contents_data_free);
-  g_simple_async_result_complete (res);
-  g_object_unref (res);
+  g_task_return_boolean (data->task, TRUE);
+  g_object_unref (data->task);
 }
 
 static void
@@ -6404,7 +6201,7 @@ load_contents_fstat_callback (GObject      *obj,
   GFileInfo *info;
 
   info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
-						   stat_res, NULL);
+                                                stat_res, NULL);
   if (info)
     {
       data->etag = g_strdup (g_file_info_get_etag (info));
@@ -6412,7 +6209,7 @@ load_contents_fstat_callback (GObject      *obj,
     }
 
   g_input_stream_close_async (stream, 0,
-			      data->cancellable,
+			      g_task_get_cancellable (data->task),
 			      load_contents_close_callback, data);
 }
 
@@ -6430,10 +6227,10 @@ load_contents_read_callback (GObject      *obj,
 
   if (read_size < 0) 
     {
-      /* Error or EOF, close the file */
-      data->error = error;
+      /* EOF, close the file */
+      g_task_return_error (data->task, error);
       g_input_stream_close_async (stream, 0,
-				  data->cancellable,
+				  g_task_get_cancellable (data->task),
 				  load_contents_close_callback, data);
     }
   else if (read_size == 0)
@@ -6441,7 +6238,7 @@ load_contents_read_callback (GObject      *obj,
       g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
 					    G_FILE_ATTRIBUTE_ETAG_VALUE,
 					    0,
-					    data->cancellable,
+					    g_task_get_cancellable (data->task),
 					    load_contents_fstat_callback,
 					    data);
     }
@@ -6454,11 +6251,12 @@ load_contents_read_callback (GObject      *obj,
 
 
       if (data->read_more_callback &&
-	  !data->read_more_callback ((char *)data->content->data, data->pos, data->user_data))
+	  !data->read_more_callback ((char *)data->content->data, data->pos,
+                                     g_async_result_get_user_data (G_ASYNC_RESULT (data->task))))
 	g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
 					      G_FILE_ATTRIBUTE_ETAG_VALUE,
 					      0,
-					      data->cancellable,
+					      g_task_get_cancellable (data->task),
 					      load_contents_fstat_callback,
 					      data);
       else 
@@ -6466,7 +6264,7 @@ load_contents_read_callback (GObject      *obj,
 				   data->content->data + data->pos,
 				   GET_CONTENT_BLOCK_SIZE,
 				   0,
-				   data->cancellable,
+				   g_task_get_cancellable (data->task),
 				   load_contents_read_callback,
 				   data);
     }
@@ -6481,7 +6279,6 @@ load_contents_open_callback (GObject      *obj,
   GFileInputStream *stream;
   LoadContentsData *data = user_data;
   GError *error = NULL;
-  GSimpleAsyncResult *res;
 
   stream = g_file_read_finish (file, open_res, &error);
 
@@ -6493,20 +6290,15 @@ load_contents_open_callback (GObject      *obj,
 				 data->content->data + data->pos,
 				 GET_CONTENT_BLOCK_SIZE,
 				 0,
-				 data->cancellable,
+				 g_task_get_cancellable (data->task),
 				 load_contents_read_callback,
 				 data);
       
     }
   else
     {
-      res = g_simple_async_result_new_take_error (G_OBJECT (data->file),
-						  data->callback,
-						  data->user_data,
-						  error);
-      g_simple_async_result_complete (res);
-      load_contents_data_free (data);
-      g_object_unref (res);
+      g_task_return_error (data->task, error);
+      g_object_unref (data->task);
     }
 }
 
@@ -6541,19 +6333,16 @@ g_file_load_partial_contents_async (GFile                 *file,
 
   g_return_if_fail (G_IS_FILE (file));
 
-  data = g_new0 (LoadContentsData, 1);
-
-  if (cancellable)
-    data->cancellable = g_object_ref (cancellable);
+  data = g_slice_new0 (LoadContentsData);
   data->read_more_callback = read_more_callback;
-  data->callback = callback;
-  data->user_data = user_data;
   data->content = g_byte_array_new ();
-  data->file = g_object_ref (file);
+
+  data->task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (data->task, data, (GDestroyNotify)load_contents_data_free);
 
   g_file_read_async (file,
 		     0,
-		     cancellable,
+		     g_task_get_cancellable (data->task),
 		     load_contents_open_callback,
 		     data);
 }
@@ -6586,31 +6375,23 @@ g_file_load_partial_contents_finish (GFile         *file,
 				     char         **etag_out,
 				     GError       **error)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
   LoadContentsData *data;
 
   g_return_val_if_fail (G_IS_FILE (file), FALSE);
-  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
+  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
   g_return_val_if_fail (contents != NULL, FALSE);
 
-  simple = G_SIMPLE_ASYNC_RESULT (res);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return FALSE;
-  
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_load_contents_async);
-  
-  data = g_simple_async_result_get_op_res_gpointer (simple);
+  task = G_TASK (res);
 
-  if (data->error)
+  if (!g_task_propagate_boolean (task, error))
     {
-      g_propagate_error (error, data->error);
-      data->error = NULL;
-      *contents = NULL;
       if (length)
-	*length = 0;
+        *length = 0;
       return FALSE;
     }
+  
+  data = g_task_get_task_data (task);
 
   if (length)
     *length = data->pos;
@@ -6790,27 +6571,19 @@ g_file_replace_contents (GFile             *file,
 }
 
 typedef struct {
-  GFile *file;
-  GError *error;
-  GCancellable *cancellable;
-  GAsyncReadyCallback callback;
-  gpointer user_data;
+  GTask *task;
   const char *content;
   gsize length;
   gsize pos;
   char *etag;
+  gboolean failed;
 } ReplaceContentsData;
 
 static void
 replace_contents_data_free (ReplaceContentsData *data)
 {
-  if (data->error)
-    g_error_free (data->error);
-  if (data->cancellable)
-    g_object_unref (data->cancellable);
-  g_object_unref (data->file);
   g_free (data->etag);
-  g_free (data);
+  g_slice_free (ReplaceContentsData, data);
 }
 
 static void
@@ -6820,21 +6593,17 @@ replace_contents_close_callback (GObject      *obj,
 {
   GOutputStream *stream = G_OUTPUT_STREAM (obj);
   ReplaceContentsData *data = user_data;
-  GSimpleAsyncResult *res;
 
   /* Ignore errors here, we're only reading anyway */
   g_output_stream_close_finish (stream, close_res, NULL);
   g_object_unref (stream);
 
-  data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
-  
-  res = g_simple_async_result_new (G_OBJECT (data->file),
-				   data->callback,
-				   data->user_data,
-				   g_file_replace_contents_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_contents_data_free);
-  g_simple_async_result_complete (res);
-  g_object_unref (res);
+  if (!data->failed)
+    {
+      data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
+      g_task_return_boolean (data->task, TRUE);
+    }
+  g_object_unref (data->task);
 }
 
 static void
@@ -6853,9 +6622,12 @@ replace_contents_write_callback (GObject      *obj,
     {
       /* Error or EOF, close the file */
       if (write_size < 0)
-	data->error = error;
+        {
+          data->failed = TRUE;
+          g_task_return_error (data->task, error);
+        }
       g_output_stream_close_async (stream, 0,
-				   data->cancellable,
+				   g_task_get_cancellable (data->task),
 				   replace_contents_close_callback, data);
     }
   else if (write_size > 0)
@@ -6864,14 +6636,14 @@ replace_contents_write_callback (GObject      *obj,
 
       if (data->pos >= data->length)
 	g_output_stream_close_async (stream, 0,
-				     data->cancellable,
+				     g_task_get_cancellable (data->task),
 				     replace_contents_close_callback, data);
       else
 	g_output_stream_write_async (stream,
 				     data->content + data->pos,
 				     data->length - data->pos,
 				     0,
-				     data->cancellable,
+				     g_task_get_cancellable (data->task),
 				     replace_contents_write_callback,
 				     data);
     }
@@ -6886,7 +6658,6 @@ replace_contents_open_callback (GObject      *obj,
   GFileOutputStream *stream;
   ReplaceContentsData *data = user_data;
   GError *error = NULL;
-  GSimpleAsyncResult *res;
 
   stream = g_file_replace_finish (file, open_res, &error);
 
@@ -6896,20 +6667,15 @@ replace_contents_open_callback (GObject      *obj,
 				   data->content + data->pos,
 				   data->length - data->pos,
 				   0,
-				   data->cancellable,
+				   g_task_get_cancellable (data->task),
 				   replace_contents_write_callback,
 				   data);
       
     }
   else
     {
-      res = g_simple_async_result_new_take_error (G_OBJECT (data->file),
-						  data->callback,
-						  data->user_data,
-						  error);
-      g_simple_async_result_complete (res);
-      replace_contents_data_free (data);
-      g_object_unref (res);
+      g_task_return_error (data->task, error);
+      g_object_unref (data->task);
     }
 }
 
@@ -6956,23 +6722,20 @@ g_file_replace_contents_async  (GFile               *file,
   g_return_if_fail (G_IS_FILE (file));
   g_return_if_fail (contents != NULL);
 
-  data = g_new0 (ReplaceContentsData, 1);
+  data = g_slice_new0 (ReplaceContentsData);
 
-  if (cancellable)
-    data->cancellable = g_object_ref (cancellable);
-  data->callback = callback;
-  data->user_data = user_data;
   data->content = contents;
   data->length = length;
-  data->pos = 0;
-  data->file = g_object_ref (file);
+
+  data->task = g_task_new (file, cancellable, callback, user_data);
+  g_task_set_task_data (data->task, data, (GDestroyNotify)replace_contents_data_free);
 
   g_file_replace_async (file,
 			etag,
 			make_backup,
 			flags,
 			0,
-			cancellable,
+			g_task_get_cancellable (data->task),
 			replace_contents_open_callback,
 			data);
 }
@@ -6998,28 +6761,18 @@ g_file_replace_contents_finish (GFile         *file,
 				char         **new_etag,
 				GError       **error)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
   ReplaceContentsData *data;
 
   g_return_val_if_fail (G_IS_FILE (file), FALSE);
-  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
+  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
 
-  simple = G_SIMPLE_ASYNC_RESULT (res);
+  task = G_TASK (res);
 
-  if (g_simple_async_result_propagate_error (simple, error))
+  if (!g_task_propagate_boolean (task, error))
     return FALSE;
-  
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_replace_contents_async);
-  
-  data = g_simple_async_result_get_op_res_gpointer (simple);
-
-  if (data->error)
-    {
-      g_propagate_error (error, data->error);
-      data->error = NULL;
-      return FALSE;
-    }
 
+  data = g_task_get_task_data (task);
 
   if (new_etag)
     {
@@ -7068,12 +6821,10 @@ g_file_start_mountable (GFile                      *file,
 
   if (iface->start_mountable == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (file),
-					   callback,
-					   user_data,
-					   G_IO_ERROR,
-					   G_IO_ERROR_NOT_SUPPORTED,
-					   _("Operation not supported"));
+      g_task_report_new_error (file, callback, user_data,
+                               g_file_start_mountable,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
 
@@ -7113,6 +6864,8 @@ g_file_start_mountable_finish (GFile                      *file,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_start_mountable))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_FILE_GET_IFACE (file);
   return (* iface->start_mountable_finish) (file, result, error);
@@ -7154,12 +6907,10 @@ g_file_stop_mountable (GFile                      *file,
 
   if (iface->stop_mountable == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (file),
-					   callback,
-					   user_data,
-					   G_IO_ERROR,
-					   G_IO_ERROR_NOT_SUPPORTED,
-					   _("Operation not supported"));
+      g_task_report_new_error (file, callback, user_data,
+                               g_file_stop_mountable,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
 
@@ -7199,6 +6950,8 @@ g_file_stop_mountable_finish (GFile                      *file,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_stop_mountable))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_FILE_GET_IFACE (file);
   return (* iface->stop_mountable_finish) (file, result, error);
@@ -7236,12 +6989,10 @@ g_file_poll_mountable (GFile                      *file,
 
   if (iface->poll_mountable == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (file),
-					   callback,
-					   user_data,
-					   G_IO_ERROR,
-					   G_IO_ERROR_NOT_SUPPORTED,
-					   _("Operation not supported"));
+      g_task_report_new_error (file, callback, user_data,
+                               g_file_poll_mountable,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
       return;
     }
 
@@ -7279,6 +7030,8 @@ g_file_poll_mountable_finish (GFile                      *file,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_poll_mountable))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_FILE_GET_IFACE (file);
   return (* iface->poll_mountable_finish) (file, result, error);
diff --git a/gio/gfileenumerator.c b/gio/gfileenumerator.c
index d8f622b..d0f91e9 100644
--- a/gio/gfileenumerator.c
+++ b/gio/gfileenumerator.c
@@ -26,7 +26,6 @@
 #include "gioscheduler.h"
 #include "gasyncresult.h"
 #include "gasynchelper.h"
-#include "gsimpleasyncresult.h"
 #include "gioerror.h"
 #include "glibintl.h"
 
@@ -335,7 +334,6 @@ g_file_enumerator_next_files_async (GFileEnumerator     *enumerator,
 				    gpointer             user_data)
 {
   GFileEnumeratorClass *class;
-  GSimpleAsyncResult *simple;
 
   g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator));
   g_return_if_fail (enumerator != NULL);
@@ -343,32 +341,30 @@ g_file_enumerator_next_files_async (GFileEnumerator     *enumerator,
 
   if (num_files == 0)
     {
-      simple = g_simple_async_result_new (G_OBJECT (enumerator),
-					  callback,
-					  user_data,
-					  g_file_enumerator_next_files_async);
-      g_simple_async_result_complete_in_idle (simple);
-      g_object_unref (simple);
+      GTask *task;
+
+      task = g_task_new (enumerator, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_file_enumerator_next_files_async);
+      g_task_return_pointer (task, NULL, NULL);
+      g_object_unref (task);
       return;
     }
   
   if (enumerator->priv->closed)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
-					   callback,
-					   user_data,
-					   G_IO_ERROR, G_IO_ERROR_CLOSED,
-					   _("File enumerator is already closed"));
+      g_task_report_new_error (enumerator, callback, user_data,
+			       g_file_enumerator_next_files_async,
+			       G_IO_ERROR, G_IO_ERROR_CLOSED,
+			       _("File enumerator is already closed"));
       return;
     }
   
   if (enumerator->priv->pending)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
-					   callback,
-					   user_data,
-					   G_IO_ERROR, G_IO_ERROR_PENDING,
-					   _("File enumerator has outstanding operation"));
+      g_task_report_new_error (enumerator, callback, user_data,
+			       g_file_enumerator_next_files_async,
+			       G_IO_ERROR, G_IO_ERROR_PENDING,
+			       _("File enumerator has outstanding operation"));
       return;
     }
 
@@ -407,10 +403,7 @@ g_file_enumerator_next_files_finish (GFileEnumerator  *enumerator,
   if (g_async_result_legacy_propagate_error (result, error))
     return NULL;
   else if (g_async_result_is_tagged (result, g_file_enumerator_next_files_async))
-    { 
-      /* Special case read of 0 files */
-      return NULL;
-    }
+    return g_task_propagate_pointer (G_TASK (result), error);
   
   class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
   return class->next_files_finish (enumerator, result, error);
@@ -459,21 +452,19 @@ g_file_enumerator_close_async (GFileEnumerator     *enumerator,
 
   if (enumerator->priv->closed)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
-					   callback,
-					   user_data,
-					   G_IO_ERROR, G_IO_ERROR_CLOSED,
-					   _("File enumerator is already closed"));
+      g_task_report_new_error (enumerator, callback, user_data,
+			       g_file_enumerator_close_async,
+			       G_IO_ERROR, G_IO_ERROR_CLOSED,
+			       _("File enumerator is already closed"));
       return;
     }
   
   if (enumerator->priv->pending)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
-					   callback,
-					   user_data,
-					   G_IO_ERROR, G_IO_ERROR_PENDING,
-					   _("File enumerator has outstanding operation"));
+      g_task_report_new_error (enumerator, callback, user_data,
+			       g_file_enumerator_close_async,
+			       G_IO_ERROR, G_IO_ERROR_PENDING,
+			       _("File enumerator has outstanding operation"));
       return;
     }
 
@@ -518,6 +509,8 @@ g_file_enumerator_close_finish (GFileEnumerator  *enumerator,
   
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_file_enumerator_close_async))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
   return class->close_finish (enumerator, result, error);
@@ -589,40 +582,29 @@ g_file_enumerator_get_container (GFileEnumerator *enumerator)
   return enumerator->priv->container;
 }
 
-typedef struct {
-  int                num_files;
-  GList             *files;
-} NextAsyncOp;
-
 static void
-next_async_op_free (NextAsyncOp *op)
+next_async_op_free (GList *files)
 {
-  /* Free the list, if finish wasn't called */
-  g_list_free_full (op->files, g_object_unref);
-  
-  g_free (op);
+  g_list_free_full (files, g_object_unref);
 }
 		    
-
-
 static void
-next_files_thread (GSimpleAsyncResult *res,
-		   GObject            *object,
-		   GCancellable       *cancellable)
+next_files_thread (GTask        *task,
+		   gpointer      source_object,
+		   gpointer      task_data,
+		   GCancellable *cancellable)
 {
-  NextAsyncOp *op;
+  GFileEnumerator *enumerator = source_object;
+  int num_files = GPOINTER_TO_INT (task_data);
   GFileEnumeratorClass *class;
+  GList *files = NULL;
   GError *error = NULL;
   GFileInfo *info;
-  GFileEnumerator *enumerator;
   int i;
 
-  enumerator = G_FILE_ENUMERATOR (object);
-  op = g_simple_async_result_get_op_res_gpointer (res);
-
-  class = G_FILE_ENUMERATOR_GET_CLASS (object);
+  class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
 
-  for (i = 0; i < op->num_files; i++)
+  for (i = 0; i < num_files; i++)
     {
       if (g_cancellable_set_error_if_cancelled (cancellable, &error))
 	info = NULL;
@@ -634,8 +616,7 @@ next_files_thread (GSimpleAsyncResult *res,
 	  /* If we get an error after first file, return that on next operation */
 	  if (error != NULL && i > 0)
 	    {
-	      if (error->domain == G_IO_ERROR &&
-		  error->code == G_IO_ERROR_CANCELLED)
+	      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 		g_error_free (error); /* Never propagate cancel errors to other call */
 	      else
 		enumerator->priv->outstanding_error = error;
@@ -645,8 +626,13 @@ next_files_thread (GSimpleAsyncResult *res,
 	  break;
 	}
       else
-	op->files = g_list_prepend (op->files, info);
+	files = g_list_prepend (files, info);
     }
+
+  if (error)
+    g_task_return_error (task, error);
+  else
+    g_task_return_pointer (task, files, (GDestroyNotify)next_async_op_free);
 }
 
 static void
@@ -657,19 +643,14 @@ g_file_enumerator_real_next_files_async (GFileEnumerator     *enumerator,
 					 GAsyncReadyCallback  callback,
 					 gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  NextAsyncOp *op;
-
-  op = g_new0 (NextAsyncOp, 1);
+  GTask *task;
 
-  op->num_files = num_files;
-  op->files = NULL;
+  task = g_task_new (enumerator, cancellable, callback, user_data);
+  g_task_set_task_data (task, GINT_TO_POINTER (num_files), NULL);
+  g_task_set_priority (task, io_priority);
 
-  res = g_simple_async_result_new (G_OBJECT (enumerator), callback, user_data, g_file_enumerator_real_next_files_async);
-  g_simple_async_result_set_op_res_gpointer (res, op, (GDestroyNotify) next_async_op_free);
-  
-  g_simple_async_result_run_in_thread (res, next_files_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, next_files_thread);
+  g_object_unref (task);
 }
 
 static GList *
@@ -677,44 +658,30 @@ g_file_enumerator_real_next_files_finish (GFileEnumerator                *enumer
 					  GAsyncResult                   *result,
 					  GError                        **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-  NextAsyncOp *op;
-  GList *res;
-
-  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;
+  g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL);
 
-  op = g_simple_async_result_get_op_res_gpointer (simple);
-
-  res = op->files;
-  op->files = NULL;
-  return res;
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 static void
-close_async_thread (GSimpleAsyncResult *res,
-		    GObject            *object,
-		    GCancellable       *cancellable)
+close_async_thread (GTask        *task,
+		    gpointer      source_object,
+		    gpointer      task_data,
+		    GCancellable *cancellable)
 {
+  GFileEnumerator *enumerator = source_object;
   GFileEnumeratorClass *class;
   GError *error = NULL;
   gboolean result;
 
-  /* Auto handling of cancelation disabled, and ignore
-     cancellation, since we want to close things anyway, although
-     possibly in a quick-n-dirty way. At least we never want to leak
-     open handles */
-  
-  class = G_FILE_ENUMERATOR_GET_CLASS (object);
-  result = class->close_fn (G_FILE_ENUMERATOR (object), cancellable, &error);
-  if (!result)
-    g_simple_async_result_take_error (res, error);
+  class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
+  result = class->close_fn (enumerator, cancellable, &error);
+  if (result)
+    g_task_return_boolean (task, TRUE);
+  else
+    g_task_return_error (task, error);
 }
 
-
 static void
 g_file_enumerator_real_close_async (GFileEnumerator     *enumerator,
 				    int                  io_priority,
@@ -722,20 +689,13 @@ g_file_enumerator_real_close_async (GFileEnumerator     *enumerator,
 				    GAsyncReadyCallback  callback,
 				    gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  
-  res = g_simple_async_result_new (G_OBJECT (enumerator),
-				   callback,
-				   user_data,
-				   g_file_enumerator_real_close_async);
+  GTask *task;
 
-  g_simple_async_result_set_handle_cancellation (res, FALSE);
+  task = g_task_new (enumerator, cancellable, callback, user_data);
+  g_task_set_priority (task, io_priority);
   
-  g_simple_async_result_run_in_thread (res,
-				       close_async_thread,
-				       io_priority,
-				       cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, close_async_thread);
+  g_object_unref (task);
 }
 
 static gboolean
@@ -743,13 +703,7 @@ g_file_enumerator_real_close_finish (GFileEnumerator  *enumerator,
                                      GAsyncResult     *result,
                                      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);
+  g_return_val_if_fail (g_task_is_valid (result, enumerator), FALSE);
 
-  if (g_simple_async_result_propagate_error (simple, error))
-    return FALSE;
-
-  return TRUE;
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
diff --git a/gio/gfileicon.c b/gio/gfileicon.c
index b537847..aa87858 100644
--- a/gio/gfileicon.c
+++ b/gio/gfileicon.c
@@ -28,7 +28,7 @@
 #include "glibintl.h"
 #include "gloadableicon.h"
 #include "ginputstream.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gioerror.h"
 
 
@@ -283,19 +283,6 @@ g_file_icon_load (GLoadableIcon  *icon,
   return G_INPUT_STREAM (stream);
 }
 
-typedef struct {
-  GLoadableIcon *icon;
-  GAsyncReadyCallback callback;
-  gpointer user_data;
-} LoadData;
-
-static void
-load_data_free (LoadData *data)
-{
-  g_object_unref (data->icon);
-  g_free (data);
-}
-
 static void
 load_async_callback (GObject      *source_object,
 		     GAsyncResult *res,
@@ -303,35 +290,14 @@ load_async_callback (GObject      *source_object,
 {
   GFileInputStream *stream;
   GError *error = NULL;
-  GSimpleAsyncResult *simple;
-  LoadData *data = user_data;
+  GTask *task = user_data;
 
   stream = g_file_read_finish (G_FILE (source_object), res, &error);
-  
   if (stream == NULL)
-    {
-      simple = g_simple_async_result_new_take_error (G_OBJECT (data->icon),
-						     data->callback,
-						     data->user_data,
-						     error);
-    }
+    g_task_return_error (task, error);
   else
-    {
-      simple = g_simple_async_result_new (G_OBJECT (data->icon),
-					  data->callback,
-					  data->user_data,
-					  g_file_icon_load_async);
-      
-      g_simple_async_result_set_op_res_gpointer (simple,
-						 stream,
-						 g_object_unref);
-  }
-
-
-  g_simple_async_result_complete (simple);
-  
-  load_data_free (data);
-  g_object_unref (simple);
+    g_task_return_pointer (task, stream, g_object_unref);
+  g_object_unref (task);
 }
 
 static void
@@ -342,17 +308,13 @@ g_file_icon_load_async (GLoadableIcon       *icon,
                         gpointer             user_data)
 {
   GFileIcon *file_icon = G_FILE_ICON (icon);
-  LoadData *data;
+  GTask *task;
 
-  data = g_new0 (LoadData, 1);
-  data->icon = g_object_ref (icon);
-  data->callback = callback;
-  data->user_data = user_data;
+  task = g_task_new (icon, cancellable, callback, user_data);
   
   g_file_read_async (file_icon->file, 0,
 		     cancellable,
-		     load_async_callback, data);
-  
+		     load_async_callback, task);
 }
 
 static GInputStream *
@@ -361,19 +323,12 @@ g_file_icon_load_finish (GLoadableIcon  *icon,
 			 char          **type,
 			 GError        **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  gpointer op;
-
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_icon_load_async);
+  g_return_val_if_fail (g_task_is_valid (res, icon), NULL);
 
   if (type)
     *type = NULL;
   
-  op = g_simple_async_result_get_op_res_gpointer (simple);
-  if (op)
-    return g_object_ref (op);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 static void
diff --git a/gio/gfileinputstream.c b/gio/gfileinputstream.c
index 0957852..ccde0bc 100644
--- a/gio/gfileinputstream.c
+++ b/gio/gfileinputstream.c
@@ -25,9 +25,9 @@
 #include <glib.h>
 #include <gfileinputstream.h>
 #include <gseekable.h>
-#include "gsimpleasyncresult.h"
 #include "gcancellable.h"
 #include "gasyncresult.h"
+#include "gtask.h"
 #include "gioerror.h"
 #include "glibintl.h"
 
@@ -215,10 +215,9 @@ g_file_input_stream_query_info_async (GFileInputStream    *stream,
   
   if (!g_input_stream_set_pending (input_stream, &error))
     {
-      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
-					    callback,
-					    user_data,
-					    error);
+      g_task_report_error (stream, callback, user_data,
+			   g_file_input_stream_query_info_async,
+			   error);
       return;
     }
 
@@ -253,6 +252,8 @@ g_file_input_stream_query_info_finish (GFileInputStream  *stream,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return NULL;
+  else if (g_async_result_is_tagged (result, g_file_input_stream_query_info_async))
+    return g_task_propagate_pointer (G_TASK (result), error);
 
   class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
   return class->query_info_finish (stream, result, error);
@@ -379,45 +380,29 @@ g_file_input_stream_seekable_truncate (GSeekable     *seekable,
  *   Default implementation of async ops    *
  ********************************************/
 
-typedef struct {
-  char *attributes;
-  GFileInfo *info;
-} QueryInfoAsyncData;
-
-static void
-query_info_data_free (QueryInfoAsyncData *data)
-{
-  if (data->info)
-    g_object_unref (data->info);
-  g_free (data->attributes);
-  g_free (data);
-}
-
 static void
-query_info_async_thread (GSimpleAsyncResult *res,
-		         GObject            *object,
-		         GCancellable       *cancellable)
+query_info_async_thread (GTask        *task,
+		         gpointer      source_object,
+			 gpointer      task_data,
+		         GCancellable *cancellable)
 {
+  GFileInputStream *stream = source_object;
+  const char *attributes = task_data;
   GFileInputStreamClass *class;
   GError *error = NULL;
-  QueryInfoAsyncData *data;
-  GFileInfo *info;
-  
-  data = g_simple_async_result_get_op_res_gpointer (res);
+  GFileInfo *info = NULL;
 
-  info = NULL;
-  
-  class = G_FILE_INPUT_STREAM_GET_CLASS (object);
+  class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
   if (class->query_info)
-    info = class->query_info (G_FILE_INPUT_STREAM (object), data->attributes, cancellable, &error);
+    info = class->query_info (stream, attributes, cancellable, &error);
   else
     g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                          _("Stream doesn't support query_info"));
 
   if (info == NULL)
-    g_simple_async_result_take_error (res, error);
+    g_task_return_error (task, error);
   else
-    data->info = info;
+    g_task_return_pointer (task, info, g_object_unref);
 }
 
 static void
@@ -428,17 +413,14 @@ g_file_input_stream_real_query_info_async (GFileInputStream    *stream,
                                            GAsyncReadyCallback  callback,
                                            gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  QueryInfoAsyncData *data;
+  GTask *task;
 
-  data = g_new0 (QueryInfoAsyncData, 1);
-  data->attributes = g_strdup (attributes);
-  
-  res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_file_input_stream_real_query_info_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
+  task = g_task_new (stream, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_strdup (attributes), g_free);
+  g_task_set_priority (task, io_priority);
   
-  g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, query_info_async_thread);
+  g_object_unref (task);
 }
 
 static GFileInfo *
@@ -446,17 +428,7 @@ g_file_input_stream_real_query_info_finish (GFileInputStream  *stream,
                                             GAsyncResult      *res,
                                             GError           **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  QueryInfoAsyncData *data;
+  g_return_val_if_fail (g_task_is_valid (res, stream), NULL);
 
-  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);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
diff --git a/gio/gfileiostream.c b/gio/gfileiostream.c
index 58adb6e..1683014 100644
--- a/gio/gfileiostream.c
+++ b/gio/gfileiostream.c
@@ -25,8 +25,8 @@
 #include <glib.h>
 #include <gfileiostream.h>
 #include <gseekable.h>
-#include "gsimpleasyncresult.h"
 #include "gasyncresult.h"
+#include "gtask.h"
 #include "gcancellable.h"
 #include "gioerror.h"
 #include "gfileoutputstream.h"
@@ -227,10 +227,9 @@ g_file_io_stream_query_info_async (GFileIOStream     *stream,
 
   if (!g_io_stream_set_pending (io_stream, &error))
     {
-      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
-					    callback,
-					    user_data,
-					    error);
+      g_task_report_error (stream, callback, user_data,
+			   g_file_io_stream_query_info_async,
+			   error);
       return;
     }
 
@@ -267,6 +266,8 @@ g_file_io_stream_query_info_finish (GFileIOStream     *stream,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return NULL;
+  else if (g_async_result_is_tagged (result, g_file_io_stream_query_info_async))
+    return g_task_propagate_pointer (G_TASK (result), error);
 
   class = G_FILE_IO_STREAM_GET_CLASS (stream);
   return class->query_info_finish (stream, result, error);
diff --git a/gio/gfileoutputstream.c b/gio/gfileoutputstream.c
index 640abe2..cf6ce15 100644
--- a/gio/gfileoutputstream.c
+++ b/gio/gfileoutputstream.c
@@ -25,8 +25,8 @@
 #include <glib.h>
 #include <gfileoutputstream.h>
 #include <gseekable.h>
-#include "gsimpleasyncresult.h"
 #include "gasyncresult.h"
+#include "gtask.h"
 #include "gcancellable.h"
 #include "gioerror.h"
 #include "glibintl.h"
@@ -225,10 +225,9 @@ g_file_output_stream_query_info_async (GFileOutputStream     *stream,
  
   if (!g_output_stream_set_pending (output_stream, &error))
     {
-      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
-					    callback,
-					    user_data,
-					    error);
+      g_task_report_error (stream, callback, user_data,
+			   g_file_output_stream_query_info_async,
+			   error);
       return;
     }
 
@@ -252,9 +251,9 @@ g_file_output_stream_query_info_async (GFileOutputStream     *stream,
  * Returns: (transfer full): A #GFileInfo for the finished query.
  **/
 GFileInfo *
-g_file_output_stream_query_info_finish (GFileOutputStream     *stream,
-					   GAsyncResult         *result,
-					   GError              **error)
+g_file_output_stream_query_info_finish (GFileOutputStream  *stream,
+					GAsyncResult       *result,
+					GError            **error)
 {
   GFileOutputStreamClass *class;
 
@@ -263,6 +262,8 @@ g_file_output_stream_query_info_finish (GFileOutputStream     *stream,
   
   if (g_async_result_legacy_propagate_error (result, error))
     return NULL;
+  else if (g_async_result_is_tagged (result, g_file_output_stream_query_info_async))
+    return g_task_propagate_pointer (G_TASK (result), error);
 
   class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
   return class->query_info_finish (stream, result, error);
@@ -482,84 +483,55 @@ g_file_output_stream_seekable_truncate (GSeekable     *seekable,
  *   Default implementation of async ops    *
  ********************************************/
 
-typedef struct {
-  char *attributes;
-  GFileInfo *info;
-} QueryInfoAsyncData;
-
-static void
-query_info_data_free (QueryInfoAsyncData *data)
-{
-  if (data->info)
-    g_object_unref (data->info);
-  g_free (data->attributes);
-  g_free (data);
-}
-
 static void
-query_info_async_thread (GSimpleAsyncResult *res,
-		       GObject *object,
-		       GCancellable *cancellable)
+query_info_async_thread (GTask        *task,
+			 gpointer      source_object,
+			 gpointer      task_data,
+			 GCancellable *cancellable)
 {
+  GFileOutputStream *stream = source_object;
+  const char *attributes = task_data;
   GFileOutputStreamClass *class;
   GError *error = NULL;
-  QueryInfoAsyncData *data;
-  GFileInfo *info;
-  
-  data = g_simple_async_result_get_op_res_gpointer (res);
+  GFileInfo *info = NULL;
 
-  info = NULL;
-  
-  class = G_FILE_OUTPUT_STREAM_GET_CLASS (object);
+  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
   if (class->query_info)
-    info = class->query_info (G_FILE_OUTPUT_STREAM (object), data->attributes, cancellable, &error);
+    info = class->query_info (stream, attributes, cancellable, &error);
   else
     g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                          _("Stream doesn't support query_info"));
 
   if (info == NULL)
-    g_simple_async_result_take_error (res, error);
+    g_task_return_error (task, error);
   else
-    data->info = info;
+    g_task_return_pointer (task, info, g_object_unref);
 }
 
 static void
-g_file_output_stream_real_query_info_async (GFileOutputStream     *stream,
-					       const char           *attributes,
-					       int                   io_priority,
-					       GCancellable         *cancellable,
-					       GAsyncReadyCallback   callback,
-					       gpointer              user_data)
+g_file_output_stream_real_query_info_async (GFileOutputStream    *stream,
+					    const char           *attributes,
+					    int                   io_priority,
+					    GCancellable         *cancellable,
+					    GAsyncReadyCallback   callback,
+					    gpointer              user_data)
 {
-  GSimpleAsyncResult *res;
-  QueryInfoAsyncData *data;
+  GTask *task;
 
-  data = g_new0 (QueryInfoAsyncData, 1);
-  data->attributes = g_strdup (attributes);
-  
-  res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_file_output_stream_real_query_info_async);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
+  task = g_task_new (stream, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_strdup (attributes), g_free);
+  g_task_set_priority (task, io_priority);
   
-  g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, query_info_async_thread);
+  g_object_unref (task);
 }
 
 static GFileInfo *
-g_file_output_stream_real_query_info_finish (GFileOutputStream     *stream,
+g_file_output_stream_real_query_info_finish (GFileOutputStream    *stream,
 					     GAsyncResult         *res,
 					     GError              **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  QueryInfoAsyncData *data;
+  g_return_val_if_fail (g_task_is_valid (res, stream), NULL);
 
-  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);
-  
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
diff --git a/gio/gloadableicon.c b/gio/gloadableicon.c
index e8eec2d..330fa4d 100644
--- a/gio/gloadableicon.c
+++ b/gio/gloadableicon.c
@@ -21,10 +21,10 @@
  */
 
 #include "config.h"
-#include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
 #include "gicon.h"
 #include "gloadableicon.h"
+#include "gasyncresult.h"
+#include "gtask.h"
 #include "glibintl.h"
 
 
@@ -156,43 +156,35 @@ g_loadable_icon_load_finish (GLoadableIcon  *icon,
 typedef struct {
   int size;
   char *type;
-  GInputStream *stream;
 } LoadData;
 
 static void
 load_data_free (LoadData *data)
 {
-  if (data->stream)
-    g_object_unref (data->stream);
   g_free (data->type);
-  g_free (data);
+  g_slice_free (LoadData, data);
 }
 
 static void
-load_async_thread (GSimpleAsyncResult *res,
-		   GObject            *object,
-		   GCancellable       *cancellable)
+load_async_thread (GTask        *task,
+		   gpointer      source_object,
+		   gpointer      task_data,
+		   GCancellable *cancellable)
 {
+  GLoadableIcon *icon = source_object;
+  LoadData *data = task_data;
   GLoadableIconIface *iface;
   GInputStream *stream;
-  LoadData *data;
   GError *error = NULL;
-  char *type = NULL;
 
-  data = g_simple_async_result_get_op_res_gpointer (res);
-  
-  iface = G_LOADABLE_ICON_GET_IFACE (object);
-  stream = iface->load (G_LOADABLE_ICON (object), data->size, &type, cancellable, &error);
+  iface = G_LOADABLE_ICON_GET_IFACE (icon);
+  stream = iface->load (icon, data->size, &data->type,
+			cancellable, &error);
 
-  if (stream == NULL)
-    {
-      g_simple_async_result_take_error (res, error);
-    }
+  if (stream)
+    g_task_return_pointer (task, stream, g_object_unref);
   else
-    {
-      data->stream = stream;
-      data->type = type;
-    }
+    g_task_return_error (task, error);
 }
 
 
@@ -204,14 +196,14 @@ g_loadable_icon_real_load_async (GLoadableIcon       *icon,
 				 GAsyncReadyCallback  callback,
 				 gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   LoadData *data;
-  
-  res = g_simple_async_result_new (G_OBJECT (icon), callback, user_data, g_loadable_icon_real_load_async);
-  data = g_new0 (LoadData, 1);
-  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify) load_data_free);
-  g_simple_async_result_run_in_thread (res, load_async_thread, 0, cancellable);
-  g_object_unref (res);
+
+  task = g_task_new (icon, cancellable, callback, user_data);
+  data = g_slice_new0 (LoadData);
+  g_task_set_task_data (task, data, (GDestroyNotify) load_data_free);
+  g_task_run_in_thread (task, load_async_thread);
+  g_object_unref (task);
 }
 
 static GInputStream *
@@ -220,21 +212,21 @@ g_loadable_icon_real_load_finish (GLoadableIcon        *icon,
 				  char                **type,
 				  GError              **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+  GTask *task;
   LoadData *data;
+  GInputStream *stream;
 
-  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;
+  g_return_val_if_fail (g_task_is_valid (res, icon), NULL);
 
-  data = g_simple_async_result_get_op_res_gpointer (simple);
+  task = G_TASK (res);
+  data = g_task_get_task_data (task);
 
-  if (type)
+  stream = g_task_propagate_pointer (task, error);
+  if (stream && type)
     {
       *type = data->type;
       data->type = NULL;
     }
 
-  return g_object_ref (data->stream);
+  return stream;
 }
diff --git a/gio/gmount.c b/gio/gmount.c
index fca17f5..437ac02 100644
--- a/gio/gmount.c
+++ b/gio/gmount.c
@@ -30,7 +30,7 @@
 #include "gmount.h"
 #include "gmountprivate.h"
 #include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gioerror.h"
 #include "glibintl.h"
 
@@ -51,7 +51,7 @@
  * 
  * Unmounting a #GMount instance is an asynchronous operation. For
  * more information about asynchronous operations, see #GAsyncResult
- * and #GSimpleAsyncResult. To unmount a #GMount instance, first call
+ * and #GTask. To unmount a #GMount instance, first call
  * g_mount_unmount_with_operation() with (at least) the #GMount instance and a
  * #GAsyncReadyCallback.  The callback will be fired when the
  * operation has resolved (either with success or failure), and a
@@ -354,14 +354,13 @@ g_mount_unmount (GMount              *mount,
 
   if (iface->unmount == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (mount),
-					   callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   /* Translators: This is an error
-					    * message for mount objects that
-					    * don't implement unmount. */
-					   _("mount doesn't implement \"unmount\""));
-
+      g_task_report_new_error (mount, callback, user_data,
+                               g_mount_unmount_with_operation,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               /* Translators: This is an error
+                                * message for mount objects that
+                                * don't implement unmount. */
+                               _("mount doesn't implement \"unmount\""));
       return;
     }
   
@@ -394,6 +393,8 @@ g_mount_unmount_finish (GMount        *mount,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_mount_unmount_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
   
   iface = G_MOUNT_GET_IFACE (mount);
   return (* iface->unmount_finish) (mount, result, error);
@@ -429,14 +430,13 @@ g_mount_eject (GMount              *mount,
 
   if (iface->eject == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (mount),
-					   callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   /* Translators: This is an error
-					    * message for mount objects that
-					    * don't implement eject. */
-					   _("mount doesn't implement \"eject\""));
-      
+      g_task_report_new_error (mount, callback, user_data,
+                               g_mount_eject_with_operation,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               /* Translators: This is an error
+                                * message for mount objects that
+                                * don't implement eject. */
+                               _("mount doesn't implement \"eject\""));
       return;
     }
   
@@ -469,6 +469,8 @@ g_mount_eject_finish (GMount        *mount,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_mount_eject_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
   
   iface = G_MOUNT_GET_IFACE (mount);
   return (* iface->eject_finish) (mount, result, error);
@@ -506,14 +508,13 @@ g_mount_unmount_with_operation (GMount              *mount,
 
   if (iface->unmount == NULL && iface->unmount_with_operation == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (mount),
-					   callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   /* Translators: This is an error
-					    * message for mount objects that
-					    * don't implement any of unmount or unmount_with_operation. */
-					   _("mount doesn't implement \"unmount\" or \"unmount_with_operation\""));
-
+      g_task_report_new_error (mount, callback, user_data,
+                               g_mount_unmount_with_operation,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               /* Translators: This is an error
+                                * message for mount objects that
+                                * don't implement any of unmount or unmount_with_operation. */
+                               _("mount doesn't implement \"unmount\" or \"unmount_with_operation\""));
       return;
     }
 
@@ -549,6 +550,8 @@ g_mount_unmount_with_operation_finish (GMount        *mount,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_mount_unmount_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_MOUNT_GET_IFACE (mount);
   if (iface->unmount_with_operation_finish != NULL)
@@ -590,13 +593,13 @@ g_mount_eject_with_operation (GMount              *mount,
 
   if (iface->eject == NULL && iface->eject_with_operation == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (mount),
-					   callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   /* Translators: This is an error
-					    * message for mount objects that
-					    * don't implement any of eject or eject_with_operation. */
-					   _("mount doesn't implement \"eject\" or \"eject_with_operation\""));
+      g_task_report_new_error (mount, callback, user_data,
+                               g_mount_eject_with_operation,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               /* Translators: This is an error
+                                * message for mount objects that
+                                * don't implement any of eject or eject_with_operation. */
+                               _("mount doesn't implement \"eject\" or \"eject_with_operation\""));
       return;
     }
 
@@ -632,6 +635,8 @@ g_mount_eject_with_operation_finish (GMount        *mount,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_mount_eject_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_MOUNT_GET_IFACE (mount);
   if (iface->eject_with_operation_finish != NULL)
@@ -676,14 +681,13 @@ g_mount_remount (GMount              *mount,
 
   if (iface->remount == NULL)
     { 
-      g_simple_async_report_error_in_idle (G_OBJECT (mount),
-					   callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   /* Translators: This is an error
-					    * message for mount objects that
-					    * don't implement remount. */
-					   _("mount doesn't implement \"remount\""));
-      
+      g_task_report_new_error (mount, callback, user_data,
+                               g_mount_remount,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               /* Translators: This is an error
+                                * message for mount objects that
+                                * don't implement remount. */
+                               _("mount doesn't implement \"remount\""));
       return;
     }
   
@@ -714,6 +718,8 @@ g_mount_remount_finish (GMount        *mount,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_mount_remount))
+    return g_task_propagate_boolean (G_TASK (result), error);
   
   iface = G_MOUNT_GET_IFACE (mount);
   return (* iface->remount_finish) (mount, result, error);
@@ -756,14 +762,13 @@ g_mount_guess_content_type (GMount              *mount,
 
   if (iface->guess_content_type == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (mount),
-                                           callback, user_data,
-                                           G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-                                           /* Translators: This is an error
-                                            * message for mount objects that
-                                            * don't implement content type guessing. */
-                                           _("mount doesn't implement content type guessing"));
-
+      g_task_report_new_error (mount, callback, user_data,
+                               g_mount_guess_content_type,
+                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               /* Translators: This is an error
+                                * message for mount objects that
+                                * don't implement content type guessing. */
+                               _("mount doesn't implement content type guessing"));
       return;
     }
   
@@ -800,6 +805,8 @@ g_mount_guess_content_type_finish (GMount        *mount,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return NULL;
+  else if (g_async_result_is_tagged (result, g_mount_guess_content_type))
+    return g_task_propagate_pointer (G_TASK (result), error);
   
   iface = G_MOUNT_GET_IFACE (mount);
   return (* iface->guess_content_type_finish) (mount, result, error);
diff --git a/gio/gunixmount.c b/gio/gunixmount.c
index d2eca7c..a012fd5 100644
--- a/gio/gunixmount.c
+++ b/gio/gunixmount.c
@@ -234,9 +234,6 @@ g_unix_mount_can_eject (GMount *mount)
 
 typedef struct {
   GUnixMount *unix_mount;
-  GAsyncReadyCallback callback;
-  gpointer user_data;
-  GCancellable *cancellable;
   int error_fd;
   GIOChannel *error_channel;
   GSource *error_channel_source;
@@ -244,35 +241,9 @@ typedef struct {
   gchar **argv;
 } UnmountEjectOp;
 
-static void 
-eject_unmount_cb (GPid pid, gint status, gpointer user_data)
+static void
+unmount_eject_op_free (UnmountEjectOp *data)
 {
-  UnmountEjectOp *data = user_data;
-  GSimpleAsyncResult *simple;
-  
-  if (WEXITSTATUS (status) != 0)
-    {
-      GError *error;
-      error = g_error_new_literal (G_IO_ERROR, 
-                                   G_IO_ERROR_FAILED,
-                                   data->error_string->str);
-      simple = g_simple_async_result_new_from_error (G_OBJECT (data->unix_mount),
-                                                     data->callback,
-                                                     data->user_data,
-                                                     error);
-      g_error_free (error);
-    }
-  else
-    {
-      simple = g_simple_async_result_new (G_OBJECT (data->unix_mount),
-                                          data->callback,
-                                          data->user_data,
-                                          NULL);
-    }
-
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
-
   if (data->error_channel_source)
     {
       g_source_destroy (data->error_channel_source);
@@ -282,21 +253,46 @@ eject_unmount_cb (GPid pid, gint status, gpointer user_data)
   g_string_free (data->error_string, TRUE);
   g_strfreev (data->argv);
   close (data->error_fd);
+  g_slice_free (UnmountEjectOp, data);
+}
+
+static void 
+eject_unmount_cb (GPid pid, gint status, gpointer user_data)
+{
+  GTask *task = user_data;
+  UnmountEjectOp *data = g_task_get_task_data (task);
+  
+  if (g_task_return_error_if_cancelled (task))
+    return;
+
   g_spawn_close_pid (pid);
-  g_free (data);
+
+  if (WEXITSTATUS (status) != 0)
+    {
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               "%s", data->error_string->str);
+    }
+  else
+    g_task_return_boolean (task, TRUE);
+
+  g_object_unref (task);
 }
 
 static gboolean
 eject_unmount_read_error (GIOChannel *channel,
-                    GIOCondition condition,
-                    gpointer user_data)
+                          GIOCondition condition,
+                          gpointer user_data)
 {
-  UnmountEjectOp *data = user_data;
+  GTask *task = user_data;
+  UnmountEjectOp *data = g_task_get_task_data (task);
   char buf[BUFSIZ];
   gsize bytes_read;
   GError *error;
   GIOStatus status;
 
+  if (g_task_return_error_if_cancelled (task))
+    return FALSE;
+
   error = NULL;
 read:
   status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error);
@@ -330,11 +326,15 @@ read:
 static gboolean
 eject_unmount_do_cb (gpointer user_data)
 {
-  UnmountEjectOp *data = (UnmountEjectOp *) user_data;
+  GTask *task = user_data;
+  UnmountEjectOp *data = g_task_get_task_data (task);
   GPid child_pid;
   GSource *child_watch;
   GError *error = NULL;
 
+  if (g_task_return_error_if_cancelled (task))
+    return G_SOURCE_REMOVE;
+
   if (!g_spawn_async_with_pipes (NULL,         /* working dir */
                                  data->argv,
                                  NULL,         /* envp */
@@ -358,34 +358,20 @@ eject_unmount_do_cb (gpointer user_data)
     goto handle_error;
 
   data->error_channel_source = g_io_create_watch (data->error_channel, G_IO_IN);
-  g_source_set_callback (data->error_channel_source,
-                         (GSourceFunc) eject_unmount_read_error, data, NULL);
-  g_source_attach (data->error_channel_source, g_main_context_get_thread_default ());
+  g_task_attach_source (task, data->error_channel_source,
+                        (GSourceFunc) eject_unmount_read_error);
 
   child_watch = g_child_watch_source_new (child_pid);
-  g_source_set_callback (child_watch, (GSourceFunc) eject_unmount_cb, data, NULL);
-  g_source_attach (child_watch, g_main_context_get_thread_default ());
+  g_task_attach_source (task, data->error_channel_source,
+                        (GSourceFunc) eject_unmount_cb);
   g_source_unref (child_watch);
 
 handle_error:
-  if (error != NULL) {
-    GSimpleAsyncResult *simple;
-    simple = g_simple_async_result_new_take_error (G_OBJECT (data->unix_mount),
-                                                   data->callback,
-                                                   data->user_data,
-                                                   error);
-    g_simple_async_result_complete (simple);
-    g_object_unref (simple);
-
-    if (data->error_string != NULL)
-      g_string_free (data->error_string, TRUE);
-
-    if (data->error_channel != NULL)
-      g_io_channel_unref (data->error_channel);
-
-    g_strfreev (data->argv);
-    g_free (data);
-  }
+  if (error != NULL)
+    {
+      g_task_return_error (task, error);
+      g_object_unref (task);
+    }
 
   return G_SOURCE_REMOVE;
 }
@@ -399,20 +385,23 @@ eject_unmount_do (GMount              *mount,
 {
   GUnixMount *unix_mount = G_UNIX_MOUNT (mount);
   UnmountEjectOp *data;
+  GTask *task;
+  GSource *timeout;
 
   data = g_new0 (UnmountEjectOp, 1);
-  data->unix_mount = unix_mount;
-  data->callback = callback;
-  data->user_data = user_data;
-  data->cancellable = cancellable;
   data->argv = g_strdupv (argv);
 
+  task = g_task_new (mount, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify)unmount_eject_op_free);
+
   if (unix_mount->volume_monitor != NULL)
     g_signal_emit_by_name (unix_mount->volume_monitor, "mount-pre-unmount", mount);
 
   g_signal_emit_by_name (mount, "pre-unmount", 0);
 
-  g_timeout_add (500, (GSourceFunc) eject_unmount_do_cb, data);
+  timeout = g_timeout_source_new (500);
+  g_task_attach_source (task, timeout, (GSourceFunc) eject_unmount_do_cb);
+  g_source_unref (timeout);
 }
 
 static void
@@ -438,7 +427,7 @@ g_unix_mount_unmount_finish (GMount       *mount,
                              GAsyncResult  *result,
                              GError       **error)
 {
-  return TRUE;
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 static void
@@ -464,7 +453,7 @@ g_unix_mount_eject_finish (GMount       *mount,
                            GAsyncResult  *result,
                            GError       **error)
 {
-  return TRUE;
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 static void
diff --git a/gio/gunixvolume.c b/gio/gunixvolume.c
index 1dc840b..1f1dab4 100644
--- a/gio/gunixvolume.c
+++ b/gio/gunixvolume.c
@@ -36,7 +36,7 @@
 #include "gthemedicon.h"
 #include "gvolume.h"
 #include "gvolumemonitor.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gioerror.h"
 #include "glibintl.h"
 /* for BUFSIZ */
@@ -260,9 +260,6 @@ _g_unix_volume_has_mount_path (GUnixVolume *volume,
 
 typedef struct {
   GUnixVolume *unix_volume;
-  GAsyncReadyCallback callback;
-  gpointer user_data;
-  GCancellable *cancellable;
   int error_fd;
   GIOChannel *error_channel;
   GSource *error_channel_source;
@@ -270,46 +267,44 @@ typedef struct {
 } EjectMountOp;
 
 static void
+eject_mount_op_free (EjectMountOp *data)
+{
+  if (data->error_string != NULL)
+    g_string_free (data->error_string, TRUE);
+
+  if (data->error_channel != NULL)
+    g_io_channel_unref (data->error_channel);
+
+  if (data->error_channel_source)
+    {
+      g_source_destroy (data->error_channel_source);
+      g_source_unref (data->error_channel_source);
+    }
+
+  if (data->error_fd != -1)
+    close (data->error_fd);
+
+  g_slice_free (EjectMountOp, data);
+}
+
+static void
 eject_mount_cb (GPid     pid,
                 gint     status,
                 gpointer user_data)
 {
-  EjectMountOp *data = user_data;
-  GSimpleAsyncResult *simple;
+  GTask *task = user_data;
+  EjectMountOp *data = g_task_get_task_data (task);
   
   if (WEXITSTATUS (status) != 0)
     {
-      GError *error;
-      error = g_error_new_literal (G_IO_ERROR, 
-                                   G_IO_ERROR_FAILED,
-                                   data->error_string->str);
-      simple = g_simple_async_result_new_from_error (G_OBJECT (data->unix_volume),
-                                                     data->callback,
-                                                     data->user_data,
-                                                     error);
-      g_error_free (error);
+      g_task_return_new_error (task,
+                               G_IO_ERROR, 
+                               G_IO_ERROR_FAILED,
+                               data->error_string->str);
     }
   else
-    {
-      simple = g_simple_async_result_new (G_OBJECT (data->unix_volume),
-                                          data->callback,
-                                          data->user_data,
-                                          NULL);
-    }
-
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
-
-  if (data->error_channel_source)
-    {
-      g_source_destroy (data->error_channel_source);
-      g_source_unref (data->error_channel_source);
-    }
-  g_io_channel_unref (data->error_channel);
-  g_string_free (data->error_string, TRUE);
-  close (data->error_fd);
-  g_spawn_close_pid (pid);
-  g_free (data);
+    g_task_return_boolean (task, TRUE);
+  g_object_unref (task);
 }
 
 static gboolean
@@ -317,7 +312,8 @@ eject_mount_read_error (GIOChannel   *channel,
                         GIOCondition  condition,
                         gpointer      user_data)
 {
-  EjectMountOp *data = user_data;
+  GTask *task = user_data;
+  EjectMountOp *data = g_task_get_task_data (task);
   char buf[BUFSIZ];
   gsize bytes_read;
   GError *error;
@@ -361,17 +357,19 @@ eject_mount_do (GVolume             *volume,
                 char               **argv)
 {
   GUnixVolume *unix_volume = G_UNIX_VOLUME (volume);
+  GTask *task;
   EjectMountOp *data;
   GPid child_pid;
   GSource *child_watch;
   GError *error;
   
-  data = g_new0 (EjectMountOp, 1);
+  data = g_slice_new0 (EjectMountOp);
   data->unix_volume = unix_volume;
-  data->callback = callback;
-  data->user_data = user_data;
-  data->cancellable = cancellable;
+  data->error_fd = -1;
   
+  task = g_task_new (unix_volume, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify) eject_mount_op_free);
+
   error = NULL;
   if (!g_spawn_async_with_pipes (NULL,         /* working dir */
                                  argv,
@@ -397,33 +395,18 @@ eject_mount_do (GVolume             *volume,
     goto handle_error;
 
   data->error_channel_source = g_io_create_watch (data->error_channel, G_IO_IN);
-  g_source_set_callback (data->error_channel_source,
-                         (GSourceFunc) eject_mount_read_error, data, NULL);
-  g_source_attach (data->error_channel_source, g_main_context_get_thread_default ());
+  g_task_attach_source (task, data->error_channel_source,
+                        (GSourceFunc) eject_mount_read_error);
 
   child_watch = g_child_watch_source_new (child_pid);
-  g_source_set_callback (child_watch, (GSourceFunc) eject_mount_cb, data, NULL);
-  g_source_attach (child_watch, g_main_context_get_thread_default ());
+  g_task_attach_source (task, child_watch, (GSourceFunc) eject_mount_cb);
   g_source_unref (child_watch);
 
 handle_error:
   if (error != NULL)
     {
-      GSimpleAsyncResult *simple;
-      simple = g_simple_async_result_new_take_error (G_OBJECT (data->unix_volume),
-                                                     data->callback,
-                                                     data->user_data,
-                                                     error);
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
-
-      if (data->error_string != NULL)
-        g_string_free (data->error_string, TRUE);
-
-      if (data->error_channel != NULL)
-        g_io_channel_unref (data->error_channel);
-
-      g_free (data);
+      g_task_return_error (task, error);
+      g_object_unref (task);
     }
 }
 
diff --git a/gio/gvolume.c b/gio/gvolume.c
index fb157d4..1f8b585 100644
--- a/gio/gvolume.c
+++ b/gio/gvolume.c
@@ -25,7 +25,7 @@
 #include "gmount.h"
 #include "gvolume.h"
 #include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gioerror.h"
 #include "glibintl.h"
 
@@ -41,9 +41,9 @@
  *
  * Mounting a #GVolume instance is an asynchronous operation. For more
  * information about asynchronous operations, see #GAsyncResult and
- * #GSimpleAsyncResult. To mount a #GVolume, first call
- * g_volume_mount() with (at least) the #GVolume instance, optionally
- * a #GMountOperation object and a #GAsyncReadyCallback. 
+ * #GTask. To mount a #GVolume, first call g_volume_mount() with (at
+ * least) the #GVolume instance, optionally a #GMountOperation object
+ * and a #GAsyncReadyCallback.
  *
  * Typically, one will only want to pass %NULL for the
  * #GMountOperation if automounting all volumes when a desktop session
@@ -327,10 +327,10 @@ g_volume_mount (GVolume             *volume,
 
   if (iface->mount_fn == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   _("volume doesn't implement mount"));
-      
+      g_task_report_new_error (volume, callback, user_data,
+			       g_volume_mount,
+			       G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			       _("volume doesn't implement mount"));
       return;
     }
   
@@ -365,6 +365,8 @@ g_volume_mount_finish (GVolume       *volume,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_volume_mount))
+    return g_task_propagate_boolean (G_TASK (result), error);
   
   iface = G_VOLUME_GET_IFACE (volume);
   return (* iface->mount_finish) (volume, result, error);
@@ -399,10 +401,10 @@ g_volume_eject (GVolume             *volume,
 
   if (iface->eject == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   _("volume doesn't implement eject"));
-      
+      g_task_report_new_error (volume, callback, user_data,
+			       g_volume_eject_with_operation,
+			       G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			       _("volume doesn't implement eject"));
       return;
     }
   
@@ -434,6 +436,8 @@ g_volume_eject_finish (GVolume       *volume,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  if (g_async_result_is_tagged (result, g_volume_eject_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
   
   iface = G_VOLUME_GET_IFACE (volume);
   return (* iface->eject_finish) (volume, result, error);
@@ -471,13 +475,13 @@ g_volume_eject_with_operation (GVolume              *volume,
 
   if (iface->eject == NULL && iface->eject_with_operation == NULL)
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (volume),
-					   callback, user_data,
-					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-					   /* Translators: This is an error
-					    * message for volume objects that
-					    * don't implement any of eject or eject_with_operation. */
-					   _("volume doesn't implement eject or eject_with_operation"));
+      g_task_report_new_error (volume, callback, user_data,
+			       g_volume_eject_with_operation,
+			       G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			       /* Translators: This is an error
+				* message for volume objects that
+				* don't implement any of eject or eject_with_operation. */
+			       _("volume doesn't implement eject or eject_with_operation"));
       return;
     }
 
@@ -513,6 +517,8 @@ g_volume_eject_with_operation_finish (GVolume        *volume,
 
   if (g_async_result_legacy_propagate_error (result, error))
     return FALSE;
+  else if (g_async_result_is_tagged (result, g_volume_eject_with_operation))
+    return g_task_propagate_boolean (G_TASK (result), error);
 
   iface = G_VOLUME_GET_IFACE (volume);
   if (iface->eject_with_operation_finish != NULL)



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