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



commit 812566bb1f1ac643dd4ece26b99dd88780de9aab
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            |   71 +++--
 gio/gfile.c             |  951 ++++++++++++++++++-----------------------------
 gio/gfileenumerator.c   |  184 ++++------
 gio/gfileicon.c         |   67 +---
 gio/gfileinputstream.c  |   80 ++---
 gio/gfileiostream.c     |   13 +-
 gio/gfileoutputstream.c |   80 ++---
 gio/gloadableicon.c     |   68 ++--
 gio/gmount.c            |  105 +++---
 gio/gunixmount.c        |  121 +++----
 gio/gunixvolume.c       |  103 +++---
 gio/gvolume.c           |   44 ++-
 12 files changed, 750 insertions(+), 1137 deletions(-)
---
diff --git a/gio/gdrive.c b/gio/gdrive.c
index c41490f..d2e92c3 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 "gthemedicon.h"
 #include "gasyncresult.h"
 #include "gioerror.h"
@@ -388,10 +388,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;
     }
   
@@ -423,6 +426,8 @@ 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);
   
@@ -461,13 +466,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;
     }
 
@@ -503,6 +511,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)
@@ -538,10 +548,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;
     }
   
@@ -571,6 +584,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);
   
@@ -741,9 +756,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;
     }
 
@@ -775,6 +794,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);
 
@@ -840,9 +861,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;
     }
 
@@ -874,6 +899,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 df865f7..d63bde0 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"
@@ -4414,12 +4413,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;
     }
 
@@ -4457,6 +4454,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);
@@ -4499,12 +4498,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;
     }
 
@@ -4544,6 +4541,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);
@@ -4589,12 +4588,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;
     }
 
@@ -4642,6 +4639,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)
@@ -4686,12 +4685,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;
     }
 
@@ -4729,6 +4726,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);
@@ -4773,12 +4772,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;
     }
 
@@ -4823,6 +4820,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)
@@ -4964,34 +4963,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;
+  GError *error = NULL;
 
-  data = g_simple_async_result_get_op_res_gpointer (res);
   info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
-
-  if (info == NULL)
-    g_simple_async_result_take_error (res, error);
+  if (info)
+    g_task_return_pointer (task, info, g_object_unref);
   else
-    data->info = info;
+    g_task_return_error (task, error);
 }
 
 static void
@@ -5003,18 +4998,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 *
@@ -5022,52 +5017,26 @@ g_file_real_query_info_finish (GFile         *file,
                                GAsyncResult  *res,
                                GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  QueryInfoAsyncData *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_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;
-  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
@@ -5078,17 +5047,13 @@ g_file_real_query_filesystem_info_async (GFile               *file,
                                          GAsyncReadyCallback  callback,
                                          gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  QueryFilesystemInfoAsyncData *data;
-
-  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);
+  GTask *task;
 
-  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 *
@@ -5096,53 +5061,26 @@ g_file_real_query_filesystem_info_finish (GFile         *file,
                                           GAsyncResult  *res,
                                           GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  QueryFilesystemInfoAsyncData *data;
-
-  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);
+  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
 
-  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);
+  GError *error = NULL;
 
   enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
-
-  if (enumerator == NULL)
-    g_simple_async_result_take_error (res, error);
+  if (error)
+    g_task_return_error (task, error);
   else
-    data->enumerator = enumerator;
+    g_task_return_pointer (task, enumerator, g_object_unref);
 }
 
 static void
@@ -5154,18 +5092,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 *
@@ -5173,25 +5111,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);
-
-  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);
+  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
-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;
@@ -5201,21 +5130,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
@@ -5225,12 +5150,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);
+  GTask *task;
 
-  g_simple_async_result_run_in_thread (res, open_read_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, open_read_async_thread);
+  g_object_unref (task);
 }
 
 static GFileInputStream *
@@ -5238,41 +5163,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;
-
-  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
-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);
+  iface = G_FILE_GET_IFACE (source_object);
 
-  stream = iface->append_to (G_FILE (object), *data, cancellable, &error);
-
-  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
@@ -5284,16 +5197,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 *
@@ -5301,41 +5215,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);
+  iface = G_FILE_GET_IFACE (source_object);
 
-  stream = iface->create (G_FILE (object), *data, cancellable, &error);
-
-  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
@@ -5347,16 +5249,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 *
@@ -5364,19 +5267,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;
-
-  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);
 }
 
 typedef struct {
@@ -5396,30 +5289,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);
 
-  data = g_simple_async_result_get_op_res_gpointer (res);
+  iface = G_FILE_GET_IFACE (source_object);
 
-  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
@@ -5432,7 +5324,7 @@ g_file_real_replace_async (GFile               *file,
                            GAsyncReadyCallback  callback,
                            gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   ReplaceAsyncData *data;
 
   data = g_new0 (ReplaceAsyncData, 1);
@@ -5440,11 +5332,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 *
@@ -5452,35 +5345,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
@@ -5490,11 +5377,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
@@ -5502,20 +5390,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;
@@ -5525,21 +5409,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
@@ -5549,12 +5429,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 *
@@ -5562,52 +5443,37 @@ g_file_real_open_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_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);
-
-  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
@@ -5619,16 +5485,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 *
@@ -5636,23 +5503,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;
@@ -5661,26 +5517,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,
@@ -5689,9 +5542,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
@@ -5704,19 +5557,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 *
@@ -5724,52 +5578,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
@@ -5780,17 +5609,14 @@ g_file_real_set_display_name_async (GFile               *file,
                                     GAsyncReadyCallback  callback,
                                     gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
-  SetDisplayNameAsyncData *data;
-
-  data = g_new0 (SetDisplayNameAsyncData, 1);
-  data->name = g_strdup (display_name);
+  GTask *task;
 
-  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 *
@@ -5798,19 +5624,9 @@ g_file_real_set_display_name_finish (GFile         *file,
                                      GAsyncResult  *res,
                                      GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  SetDisplayNameAsyncData *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_set_display_name_async);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-
-  data = g_simple_async_result_get_op_res_gpointer (simple);
-  if (data->file)
-    return g_object_ref (data->file);
-
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 typedef struct {
@@ -5827,17 +5643,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),
@@ -5856,18 +5671,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);
+  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_simple_async_result_run_in_thread (res, set_info_async_thread, io_priority, cancellable);
-  g_object_unref (res);
+  g_task_run_in_thread (task, set_info_async_thread);
+  g_object_unref (task);
 }
 
 static gboolean
@@ -5876,12 +5692,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);
@@ -5893,9 +5708,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;
@@ -5903,9 +5719,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
@@ -5915,29 +5731,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);
 }
 
 
@@ -6053,6 +5863,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);
 }
 
@@ -6273,11 +6085,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;
     }
 
@@ -6309,6 +6120,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);
 
@@ -6485,12 +6298,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;
@@ -6500,15 +6309,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
@@ -6518,19 +6322,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
@@ -6543,7 +6341,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));
@@ -6551,7 +6349,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);
 }
 
@@ -6569,10 +6367,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)
@@ -6580,7 +6378,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);
     }
@@ -6593,11 +6391,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
@@ -6605,7 +6404,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);
     }
@@ -6620,7 +6419,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);
 
@@ -6632,19 +6430,14 @@ 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);
     }
 }
 
@@ -6680,19 +6473,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);
 }
@@ -6725,32 +6515,24 @@ 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);
+  task = G_TASK (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);
-
-  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;
       return FALSE;
     }
 
+  data = g_task_get_task_data (task);
+
   if (length)
     *length = data->pos;
 
@@ -6929,27 +6711,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
@@ -6959,21 +6733,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
@@ -6992,9 +6762,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)
@@ -7003,14 +6776,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);
     }
@@ -7025,7 +6798,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);
 
@@ -7035,19 +6807,14 @@ 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);
     }
 }
 
@@ -7094,23 +6861,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);
 }
@@ -7136,27 +6900,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)
     {
@@ -7206,12 +6961,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;
     }
 
@@ -7251,6 +7004,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);
@@ -7296,12 +7051,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;
     }
 
@@ -7341,6 +7094,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);
@@ -7380,12 +7135,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;
     }
 
@@ -7423,6 +7176,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..95c1cce 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_return_val_if_fail (g_task_is_valid (result, enumerator), NULL);
 
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == 
-	    g_file_enumerator_real_next_files_async);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-
-  op = g_simple_async_result_get_op_res_gpointer (simple);
-
-  res = op->files;
-  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..26f2825 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);
-  
+                     cancellable,
+                     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..73e7b78 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;
     }
 
@@ -227,7 +226,7 @@ g_file_input_stream_query_info_async (GFileInputStream    *stream,
   stream->priv->outstanding_callback = callback;
   g_object_ref (stream);
   klass->query_info_async (stream, attributes, io_priority, cancellable,
-			      async_ready_callback_wrapper, user_data);
+                           async_ready_callback_wrapper, user_data);
 }
 
 /**
@@ -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..7eb6186 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;
     }
 
@@ -239,7 +238,7 @@ g_file_io_stream_query_info_async (GFileIOStream     *stream,
   stream->priv->outstanding_callback = callback;
   g_object_ref (stream);
   klass->query_info_async (stream, attributes, io_priority, cancellable,
-			      async_ready_callback_wrapper, user_data);
+                           async_ready_callback_wrapper, user_data);
 }
 
 /**
@@ -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..7b77ba5 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;
     }
 
@@ -237,7 +236,7 @@ g_file_output_stream_query_info_async (GFileOutputStream     *stream,
   stream->priv->outstanding_callback = callback;
   g_object_ref (stream);
   klass->query_info_async (stream, attributes, io_priority, cancellable,
-			      async_ready_callback_wrapper, user_data);
+                           async_ready_callback_wrapper, user_data);
 }
 
 /**
@@ -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,45 +483,29 @@ 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
@@ -531,17 +516,14 @@ g_file_output_stream_real_query_info_async (GFileOutputStream     *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_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 *
@@ -549,17 +531,7 @@ 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..e247490 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 c7ff943..ac0179e 100644
--- a/gio/gmount.c
+++ b/gio/gmount.c
@@ -31,7 +31,7 @@
 #include "gmountprivate.h"
 #include "gthemedicon.h"
 #include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gioerror.h"
 #include "glibintl.h"
 
@@ -52,7 +52,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
@@ -386,14 +386,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;
     }
   
@@ -426,6 +425,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);
@@ -461,14 +462,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;
     }
   
@@ -501,6 +501,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);
@@ -538,14 +540,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;
     }
 
@@ -581,6 +582,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)
@@ -622,13 +625,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;
     }
 
@@ -664,6 +667,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)
@@ -708,14 +713,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;
     }
   
@@ -746,6 +750,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);
@@ -788,14 +794,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;
     }
   
@@ -832,6 +837,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 f2e67c6..2bd4116 100644
--- a/gio/gunixmount.c
+++ b/gio/gunixmount.c
@@ -245,9 +245,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;
@@ -255,35 +252,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);
@@ -293,21 +264,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);
@@ -341,11 +337,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 */
@@ -369,34 +369,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;
 }
@@ -410,20 +396,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
@@ -449,7 +438,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
@@ -475,7 +464,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 f559ca9..da6b552 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 */
@@ -270,9 +270,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;
@@ -280,46 +277,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
@@ -327,7 +322,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;
@@ -371,17 +367,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,
@@ -407,33 +405,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 8338329..aa5e40e 100644
--- a/gio/gvolume.c
+++ b/gio/gvolume.c
@@ -26,7 +26,7 @@
 #include "gvolume.h"
 #include "gthemedicon.h"
 #include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gioerror.h"
 #include "glibintl.h"
 
@@ -42,9 +42,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
@@ -359,10 +359,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;
     }
   
@@ -397,6 +397,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);
@@ -431,10 +433,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;
     }
   
@@ -466,6 +468,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);
@@ -503,13 +507,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;
     }
 
@@ -545,6 +549,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]