[glib/wip/task: 8/12] gio: port networking classes from GSimpleAsyncResult to GTask



commit d572b65bbcccfcb7980894081f7850d95a9122f7
Author: Dan Winship <danw gnome org>
Date:   Thu Aug 2 15:48:22 2012 -0400

    gio: port networking 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/gdummyproxyresolver.c      |   40 +++-------
 gio/gnetworkaddress.c          |   61 ++++++++-------
 gio/gnetworkmonitor.c          |   25 ++----
 gio/gnetworkservice.c          |   95 +++++++---------------
 gio/gproxyaddressenumerator.c  |  138 ++++++++++++--------------------
 gio/gresolver.c                |   21 ++---
 gio/gsocketaddressenumerator.c |   31 +++-----
 gio/gsocketclient.c            |  131 +++++++++++++++----------------
 gio/gsocketconnection.c        |   67 ++++++----------
 gio/gsocketinputstream.c       |    4 +-
 gio/gsocketlistener.c          |   74 ++++++------------
 gio/gsocketoutputstream.c      |    4 +-
 gio/gsocks4aproxy.c            |   99 ++++++++---------------
 gio/gsocks5proxy.c             |  169 +++++++++++++++++++---------------------
 gio/gtcpconnection.c           |   90 ++++++----------------
 gio/gunixconnection.c          |   90 +++++++--------------
 16 files changed, 435 insertions(+), 704 deletions(-)
---
diff --git a/gio/gdummyproxyresolver.c b/gio/gdummyproxyresolver.c
index e3ba2b5..8f3969e 100644
--- a/gio/gdummyproxyresolver.c
+++ b/gio/gdummyproxyresolver.c
@@ -29,7 +29,7 @@
 #include "gasyncresult.h"
 #include "gcancellable.h"
 #include "gproxyresolver.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 
 #include "giomodule.h"
 #include "giomodule-priv.h"
@@ -93,29 +93,17 @@ g_dummy_proxy_resolver_lookup_async (GProxyResolver      *resolver,
 				     gpointer             user_data)
 {
   GError *error = NULL;
-  GSimpleAsyncResult *simple;
+  GTask *task;
   gchar **proxies;
 
-  proxies = g_dummy_proxy_resolver_lookup (resolver, uri, cancellable, &error);
+  task = g_task_new (resolver, cancellable, callback, user_data);
 
-  
-  simple = g_simple_async_result_new (G_OBJECT (resolver),
-				      callback, user_data,
-				      g_dummy_proxy_resolver_lookup_async);
-
-  if (proxies == NULL)
-    {
-      g_simple_async_result_take_error (simple, error);
-    }
+  proxies = g_dummy_proxy_resolver_lookup (resolver, uri, cancellable, &error);
+  if (proxies)
+    g_task_return_pointer (task, proxies, (GDestroyNotify) g_strfreev);
   else
-    {
-      g_simple_async_result_set_op_res_gpointer (simple,
-						 proxies,
-						 NULL);
-    }
-
-  g_simple_async_result_complete_in_idle (simple);
-  g_object_unref (simple);
+    g_task_return_error (task, error);
+  g_object_unref (task);
 }
 
 static gchar **
@@ -123,17 +111,9 @@ g_dummy_proxy_resolver_lookup_finish (GProxyResolver     *resolver,
 				      GAsyncResult       *result,
 				      GError            **error)
 {
-  if (G_IS_SIMPLE_ASYNC_RESULT (result))
-    {
-      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
-      if (g_simple_async_result_propagate_error (simple, error))
-        return NULL;
-
-      return g_simple_async_result_get_op_res_gpointer (simple);
-    }
+  g_return_val_if_fail (g_task_is_valid (result, resolver), NULL);
 
-  return NULL;
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 static void
diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c
index cbb272d..b67a86d 100644
--- a/gio/gnetworkaddress.c
+++ b/gio/gnetworkaddress.c
@@ -32,7 +32,7 @@
 #include "gnetworkingprivate.h"
 #include "gproxyaddressenumerator.h"
 #include "gresolver.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gsocketaddressenumerator.h"
 #include "gioerror.h"
 #include "gsocketconnectable.h"
@@ -852,19 +852,19 @@ got_addresses (GObject      *source_object,
                GAsyncResult *result,
                gpointer      user_data)
 {
-  GSimpleAsyncResult *simple = user_data;
-  GNetworkAddressAddressEnumerator *addr_enum =
-    g_simple_async_result_get_op_res_gpointer (simple);
+  GTask *task = user_data;
+  GNetworkAddressAddressEnumerator *addr_enum = g_task_get_source_object (task);
   GResolver *resolver = G_RESOLVER (source_object);
   GList *addresses;
   GError *error = NULL;
+  GSocketAddress *sockaddr;
 
   if (!addr_enum->addr->priv->sockaddrs)
     {
       addresses = g_resolver_lookup_by_name_finish (resolver, result, &error);
 
       if (error)
-        g_simple_async_result_take_error (simple, error);
+        g_task_return_error (task, error);
       else
         g_network_address_set_addresses (addr_enum->addr, addresses);
     }
@@ -874,8 +874,17 @@ got_addresses (GObject      *source_object,
   addr_enum->addresses = addr_enum->addr->priv->sockaddrs;
   addr_enum->next = addr_enum->addresses;
 
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
+  if (addr_enum->next)
+    {
+      sockaddr = g_object_ref (addr_enum->next->data);
+      addr_enum->next = addr_enum->next->next;
+    }
+  else
+    sockaddr = NULL;
+
+  if (!error)
+    g_task_return_pointer (task, sockaddr, g_object_unref);
+  g_object_unref (task);
 }
 
 static void
@@ -886,11 +895,10 @@ g_network_address_address_enumerator_next_async (GSocketAddressEnumerator  *enum
 {
   GNetworkAddressAddressEnumerator *addr_enum =
     G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
-  GSimpleAsyncResult *simple;
+  GSocketAddress *sockaddr;
+  GTask *task;
 
-  simple = g_simple_async_result_new (G_OBJECT (enumerator),
-                                      callback, user_data,
-                                      g_network_address_address_enumerator_next_async);
+  task = g_task_new (addr_enum, cancellable, callback, user_data);
 
   if (addr_enum->addresses == NULL)
     {
@@ -898,11 +906,10 @@ g_network_address_address_enumerator_next_async (GSocketAddressEnumerator  *enum
         {
           GResolver *resolver = g_resolver_get_default ();
 
-          g_simple_async_result_set_op_res_gpointer (simple, g_object_ref (addr_enum), g_object_unref);
           g_resolver_lookup_by_name_async (resolver,
                                            addr_enum->addr->priv->hostname,
                                            cancellable,
-                                           got_addresses, simple);
+                                           got_addresses, task);
           return;
         }
 
@@ -910,8 +917,16 @@ g_network_address_address_enumerator_next_async (GSocketAddressEnumerator  *enum
       addr_enum->next = addr_enum->addresses;
     }
 
-  g_simple_async_result_complete_in_idle (simple);
-  g_object_unref (simple);
+  if (addr_enum->next)
+    {
+      sockaddr = g_object_ref (addr_enum->next->data);
+      addr_enum->next = addr_enum->next->next;
+    }
+  else
+    sockaddr = NULL;
+
+  g_task_return_pointer (task, sockaddr, g_object_unref);
+  g_object_unref (task);
 }
 
 static GSocketAddress *
@@ -919,21 +934,9 @@ g_network_address_address_enumerator_next_finish (GSocketAddressEnumerator  *enu
                                                   GAsyncResult              *result,
                                                   GError                   **error)
 {
-  GNetworkAddressAddressEnumerator *addr_enum =
-    G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-  GSocketAddress *sockaddr;
+  g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL);
 
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-  else if (!addr_enum->next)
-    return NULL;
-  else
-    {
-      sockaddr = addr_enum->next->data;
-      addr_enum->next = addr_enum->next->next;
-      return g_object_ref (sockaddr);
-    }
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 static void
diff --git a/gio/gnetworkmonitor.c b/gio/gnetworkmonitor.c
index f3359ef..a133d41 100644
--- a/gio/gnetworkmonitor.c
+++ b/gio/gnetworkmonitor.c
@@ -28,7 +28,7 @@
 #include "ginitable.h"
 #include "gioenumtypes.h"
 #include "giomodule-priv.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 
 /**
  * SECTION:gnetworkmonitor
@@ -148,18 +148,15 @@ g_network_monitor_real_can_reach_async (GNetworkMonitor     *monitor,
                                         GAsyncReadyCallback  callback,
                                         gpointer             user_data)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
   GError *error = NULL;
 
-  simple = g_simple_async_result_new (G_OBJECT (monitor),
-                                      callback, user_data,
-                                      g_network_monitor_real_can_reach_async);
+  task = g_task_new (monitor, cancellable, callback, user_data);
   if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error))
-    g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+    g_task_return_boolean (task, TRUE);
   else
-    g_simple_async_result_take_error (simple, error);
-  g_simple_async_result_complete_in_idle (simple);
-  g_object_unref (simple);
+    g_task_return_error (task, error);
+  g_object_unref (task);
 }
 
 /**
@@ -199,15 +196,9 @@ g_network_monitor_real_can_reach_finish (GNetworkMonitor  *monitor,
                                          GAsyncResult     *result,
                                          GError          **error)
 {
-  GSimpleAsyncResult *simple;
+  g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);
 
-  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (monitor), g_network_monitor_real_can_reach_async), FALSE);
-
-  simple = G_SIMPLE_ASYNC_RESULT (result);
-  if (g_simple_async_result_propagate_error (simple, error))
-    return FALSE;
-  else
-    return g_simple_async_result_get_op_res_gboolean (simple);
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 /**
diff --git a/gio/gnetworkservice.c b/gio/gnetworkservice.c
index 39b78d6..28186e3 100644
--- a/gio/gnetworkservice.c
+++ b/gio/gnetworkservice.c
@@ -33,7 +33,7 @@
 #include "gnetworkaddress.h"
 #include "gnetworkingprivate.h"
 #include "gresolver.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gsocketaddressenumerator.h"
 #include "gsocketconnectable.h"
 #include "gsrvtarget.h"
@@ -395,9 +395,6 @@ typedef struct {
 
   GError *error;
 
-  /* For async operation */
-  GCancellable *cancellable;
-  GSimpleAsyncResult *result;
 } GNetworkServiceAddressEnumerator;
 
 typedef struct {
@@ -530,13 +527,13 @@ g_network_service_address_enumerator_next (GSocketAddressEnumerator  *enumerator
   return ret;
 }
 
-static void next_async_resolved_targets   (GObject                          *source_object,
-                                           GAsyncResult                     *result,
-                                           gpointer                          user_data);
-static void next_async_have_targets       (GNetworkServiceAddressEnumerator *srv_enum);
-static void next_async_have_address       (GObject                          *source_object,
-                                           GAsyncResult                     *result,
-                                           gpointer                          user_data);
+static void next_async_resolved_targets   (GObject      *source_object,
+                                           GAsyncResult *result,
+                                           gpointer      user_data);
+static void next_async_have_targets       (GTask        *srv_enum);
+static void next_async_have_address       (GObject      *source_object,
+                                           GAsyncResult *result,
+                                           gpointer      user_data);
 
 static void
 g_network_service_address_enumerator_next_async (GSocketAddressEnumerator  *enumerator,
@@ -546,15 +543,9 @@ g_network_service_address_enumerator_next_async (GSocketAddressEnumerator  *enum
 {
   GNetworkServiceAddressEnumerator *srv_enum =
     G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (enumerator);
+  GTask *task;
 
-  g_return_if_fail (srv_enum->result == NULL);
-
-  srv_enum->result = g_simple_async_result_new (G_OBJECT (enumerator),
-                                                callback, user_data,
-                                                g_network_service_address_enumerator_next_async);
-
-  if (cancellable)
-    srv_enum->cancellable = g_object_ref (cancellable);
+  task = g_task_new (enumerator, cancellable, callback, user_data);
 
   /* If we haven't yet resolved srv, do that */
   if (!srv_enum->srv->priv->targets)
@@ -565,10 +556,10 @@ g_network_service_address_enumerator_next_async (GSocketAddressEnumerator  *enum
                                        srv_enum->srv->priv->domain,
                                        cancellable,
                                        next_async_resolved_targets,
-                                       srv_enum);
+                                       task);
     }
   else
-    next_async_have_targets (srv_enum);
+    next_async_have_targets (task);
 }
 
 static void
@@ -576,7 +567,8 @@ next_async_resolved_targets (GObject      *source_object,
                              GAsyncResult *result,
                              gpointer      user_data)
 {
-  GNetworkServiceAddressEnumerator *srv_enum = user_data;
+  GTask *task = user_data;
+  GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task);
   GError *error = NULL;
   GList *targets;
 
@@ -593,23 +585,21 @@ next_async_resolved_targets (GObject      *source_object,
 
   if (error)
     {
-      GSimpleAsyncResult *simple = srv_enum->result;
-
-      srv_enum->result = NULL;
-      g_simple_async_result_take_error (simple, error);
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
+      g_task_return_error (task, error);
+      g_object_unref (task);
     }
   else
     {
       srv_enum->t = srv_enum->srv->priv->targets = targets;
-      next_async_have_targets (srv_enum);
+      next_async_have_targets (task);
     }
 }
 
 static void
-next_async_have_targets (GNetworkServiceAddressEnumerator *srv_enum)
+next_async_have_targets (GTask *task)
 {
+  GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task);
+
   /* Delegate to GNetworkAddress */
   if (srv_enum->addr_enum == NULL && srv_enum->t)
     {
@@ -631,23 +621,18 @@ next_async_have_targets (GNetworkServiceAddressEnumerator *srv_enum)
   if (srv_enum->addr_enum)
     {
       g_socket_address_enumerator_next_async (srv_enum->addr_enum,
-                                              srv_enum->cancellable,
+                                              g_task_get_cancellable (task),
                                               next_async_have_address,
-                                              srv_enum);
+                                              task);
     }
   else
     {
-      GSimpleAsyncResult *simple = srv_enum->result;
-      srv_enum->result = NULL;
-
       if (srv_enum->error)
         {
-          g_simple_async_result_take_error (simple, srv_enum->error);
+          g_task_return_error (task, srv_enum->error);
           srv_enum->error = NULL;
         }
-
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
+      g_object_unref (task);
     }
 }
 
@@ -656,7 +641,8 @@ next_async_have_address (GObject      *source_object,
                          GAsyncResult *result,
                          gpointer      user_data)
 {
-  GNetworkServiceAddressEnumerator *srv_enum = user_data;
+  GTask *task = user_data;
+  GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task);
   GSocketAddress *address;
   GError *error = NULL;
   
@@ -677,20 +663,12 @@ next_async_have_address (GObject      *source_object,
       g_object_unref (srv_enum->addr_enum);
       srv_enum->addr_enum = NULL;
 
-      next_async_have_targets (srv_enum);
+      next_async_have_targets (task);
     }
   else
     {
-      GSimpleAsyncResult *simple = srv_enum->result;
-
-      srv_enum->result = NULL;
-
-      if (address)
-        g_simple_async_result_set_op_res_gpointer (simple,
-                                                   address, g_object_unref);
-
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
+      g_task_return_pointer (task, address, g_object_unref);
+      g_object_unref (task);
     }
 }
 
@@ -699,14 +677,7 @@ g_network_service_address_enumerator_next_finish (GSocketAddressEnumerator  *enu
                                                   GAsyncResult              *result,
                                                   GError                   **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-  GSocketAddress *sockaddr;
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-
-  sockaddr = g_simple_async_result_get_op_res_gpointer (simple);
-  return sockaddr ? g_object_ref (sockaddr) : NULL;
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 static void
@@ -729,12 +700,6 @@ g_network_service_address_enumerator_finalize (GObject *object)
   if (srv_enum->resolver)
     g_object_unref (srv_enum->resolver);
 
-  if (srv_enum->result)
-    g_object_unref (srv_enum->result);
-
-  if (srv_enum->cancellable)
-    g_object_unref (srv_enum->cancellable);
-
   if (srv_enum->error)
     g_error_free (srv_enum->error);
 
diff --git a/gio/gproxyaddressenumerator.c b/gio/gproxyaddressenumerator.c
index 1f2ef12..816496f 100644
--- a/gio/gproxyaddressenumerator.c
+++ b/gio/gproxyaddressenumerator.c
@@ -33,7 +33,7 @@
 #include "gproxy.h"
 #include "gproxyaddress.h"
 #include "gproxyresolver.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gresolver.h"
 #include "gsocketaddress.h"
 #include "gsocketaddressenumerator.h"
@@ -71,10 +71,6 @@ struct _GProxyAddressEnumeratorPrivate
   gboolean                  supports_hostname;
   GList			   *next_dest_ip;
   GError                   *last_error;
-
-  /* Async attributes */
-  GSimpleAsyncResult *simple;
-  GCancellable       *cancellable;
 };
 
 static void
@@ -313,31 +309,25 @@ g_proxy_address_enumerator_next (GSocketAddressEnumerator  *enumerator,
 
 
 static void
-complete_async (GProxyAddressEnumeratorPrivate *priv)
+complete_async (GTask *task)
 {
-  GSimpleAsyncResult *simple = priv->simple;
-
-  if (priv->cancellable)
-    {
-      g_object_unref (priv->cancellable);
-      priv->cancellable = NULL;
-    }
-
-  priv->simple = NULL;
+  GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
 
   if (priv->last_error)
     {
-      g_simple_async_result_take_error (simple, priv->last_error);
+      g_task_return_error (task, priv->last_error);
       priv->last_error = NULL;
     }
+  else
+    g_task_return_pointer (task, NULL, NULL);
 
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
+  g_object_unref (task);
 }
 
 static void
-save_result (GProxyAddressEnumeratorPrivate *priv)
+return_result (GTask *task)
 {
+  GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
   GSocketAddress *result;
 
   if (strcmp ("direct", priv->proxy_type) == 0)
@@ -397,9 +387,8 @@ save_result (GProxyAddressEnumeratorPrivate *priv)
 	}
     }
 
-  g_simple_async_result_set_op_res_gpointer (priv->simple,
-					     result,
-					     g_object_unref);
+  g_task_return_pointer (task, result, g_object_unref);
+  g_object_unref (task);
 }
 
 static void address_enumerate_cb (GObject      *object,
@@ -407,8 +396,10 @@ static void address_enumerate_cb (GObject      *object,
 				  gpointer	user_data);
 
 static void
-next_proxy (GProxyAddressEnumeratorPrivate *priv)
+next_proxy (GTask *task)
 {
+  GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
+
   if (*priv->next_proxy)
     {
       g_object_unref (priv->addr_enum);
@@ -425,14 +416,14 @@ next_proxy (GProxyAddressEnumeratorPrivate *priv)
       if (priv->addr_enum)
 	{
 	  g_socket_address_enumerator_next_async (priv->addr_enum,
-						  priv->cancellable,
-						  address_enumerate_cb,
-						  priv);
+                                                  g_task_get_cancellable (task),
+                                                  address_enumerate_cb,
+                                                  task);
 	  return;
 	}
     }
 
-  complete_async (priv);
+  complete_async (task);
 }
 
 static void
@@ -440,21 +431,19 @@ dest_hostname_lookup_cb (GObject           *object,
 			 GAsyncResult      *result,
 			 gpointer           user_data)
 {
-  GProxyAddressEnumeratorPrivate *priv = user_data;
+  GTask *task = user_data;
+  GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
 
   g_clear_error (&priv->last_error);
   priv->dest_ips = g_resolver_lookup_by_name_finish (G_RESOLVER (object),
 						     result,
 						     &priv->last_error);
   if (priv->dest_ips)
-    {
-      save_result (priv);
-      complete_async (priv);
-    }
+    return_result (task);
   else
     {
       g_clear_object (&priv->proxy_address);
-      next_proxy (priv);
+      next_proxy (task);
     }
 }
 
@@ -463,7 +452,8 @@ address_enumerate_cb (GObject	   *object,
 		      GAsyncResult *result,
 		      gpointer	    user_data)
 {
-  GProxyAddressEnumeratorPrivate *priv = user_data;
+  GTask *task = user_data;
+  GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
 
   g_clear_error (&priv->last_error);
   priv->proxy_address =
@@ -477,19 +467,18 @@ address_enumerate_cb (GObject	   *object,
 	  GResolver *resolver;
 	  resolver = g_resolver_get_default();
 	  g_resolver_lookup_by_name_async (resolver,
-					   priv->dest_hostname,
-					   priv->cancellable,
-					   dest_hostname_lookup_cb,
-					   priv);
+                                           priv->dest_hostname,
+                                           g_task_get_cancellable (task),
+                                           dest_hostname_lookup_cb,
+                                           task);
 	  g_object_unref (resolver);
 	  return;
 	}
 
-      save_result (priv);
-      complete_async (priv);
+      return_result (task);
     }
   else
-    next_proxy (priv);
+    next_proxy (task);
 }
 
 static void
@@ -497,18 +486,19 @@ proxy_lookup_cb (GObject      *object,
 		 GAsyncResult *result,
 		 gpointer      user_data)
 {
-  GError *error = NULL;
-  GProxyAddressEnumeratorPrivate *priv = user_data;
-  GSimpleAsyncResult *simple = priv->simple;
+  GTask *task = user_data;
+  GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
 
+  g_clear_error (&priv->last_error);
   priv->proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (object),
-						  result,
-						  &error);
+                                                  result,
+                                                  &priv->last_error);
   priv->next_proxy = priv->proxies;
 
-  if (error)
+  if (priv->last_error)
     {
-      g_simple_async_result_take_error (simple, error);
+      complete_async (task);
+      return;
     }
   else
     {
@@ -516,14 +506,14 @@ proxy_lookup_cb (GObject      *object,
       if (priv->addr_enum)
 	{
 	  g_socket_address_enumerator_next_async (priv->addr_enum,
-						  priv->cancellable,
-						  address_enumerate_cb,
-						  priv);
+                                                  g_task_get_cancellable (task),
+                                                  address_enumerate_cb,
+                                                  task);
 	  return;
 	}
     }
 
-  complete_async (priv); 
+  complete_async (task);
 }
 
 static void
@@ -533,15 +523,10 @@ g_proxy_address_enumerator_next_async (GSocketAddressEnumerator *enumerator,
 				       gpointer                  user_data)
 {
   GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (enumerator);
+  GTask *task;
 
-  g_return_if_fail (priv->simple == NULL);
-  g_return_if_fail (priv->cancellable == NULL);
-
-  priv->simple = g_simple_async_result_new (G_OBJECT (enumerator),
-					    callback, user_data,
-					    g_proxy_address_enumerator_next_async);
-
-  priv->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+  task = g_task_new (enumerator, cancellable, callback, user_data);
+  g_task_set_task_data (task, priv, NULL);
 
   if (priv->proxies == NULL)
     {
@@ -550,7 +535,7 @@ g_proxy_address_enumerator_next_async (GSocketAddressEnumerator *enumerator,
 				     priv->dest_uri,
 				     cancellable,
 				     proxy_lookup_cb,
-				     priv);
+				     task);
       return;
     }
 
@@ -558,28 +543,20 @@ g_proxy_address_enumerator_next_async (GSocketAddressEnumerator *enumerator,
     {
       if (priv->proxy_address)
 	{
-	  save_result (priv);
+	  return_result (task);
+	  return;
 	}
       else
 	{
 	  g_socket_address_enumerator_next_async (priv->addr_enum,
 						  cancellable,
 						  address_enumerate_cb,
-						  priv);
+						  task);
 	  return;
 	}
     }
 
-  g_simple_async_result_complete_in_idle (priv->simple);
-
-  g_object_unref (priv->simple);
-  priv->simple = NULL;
-
-  if (priv->cancellable)
-    {
-      g_object_unref (priv->cancellable);
-      priv->cancellable = NULL;
-    }
+  complete_async (task);
 }
 
 static GSocketAddress *
@@ -587,17 +564,9 @@ g_proxy_address_enumerator_next_finish (GSocketAddressEnumerator  *enumerator,
 					GAsyncResult              *result,
 					GError                   **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-  GSocketAddress *address;
+  g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL);
 
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-
-  address = g_simple_async_result_get_op_res_gpointer (simple);
-  if (address)
-    g_object_ref (address);
-
-  return address;
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 static void
@@ -702,9 +671,6 @@ g_proxy_address_enumerator_finalize (GObject *object)
   g_free (priv->proxy_username);
   g_free (priv->proxy_password);
 
-  if (priv->cancellable)
-    g_object_unref (priv->cancellable);
-
   g_clear_error (&priv->last_error);
 
   G_OBJECT_CLASS (g_proxy_address_enumerator_parent_class)->finalize (object);
diff --git a/gio/gresolver.c b/gio/gresolver.c
index 4ca4e00..718dc48 100644
--- a/gio/gresolver.c
+++ b/gio/gresolver.c
@@ -30,6 +30,7 @@
 #include "ginetaddress.h"
 #include "ginetsocketaddress.h"
 #include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gsrvtarget.h"
 #include "gthreadedresolver.h"
 
@@ -395,15 +396,13 @@ g_resolver_lookup_by_name_async (GResolver           *resolver,
   addr = g_inet_address_new_from_string (hostname);
   if (addr)
     {
-      GSimpleAsyncResult *simple;
+      GTask *task;
 
-      simple = g_simple_async_result_new (G_OBJECT (resolver),
-                                          callback, user_data,
-                                          g_resolver_lookup_by_name_async);
-
-      g_simple_async_result_set_op_res_gpointer (simple, addr, g_object_unref);
-      g_simple_async_result_complete_in_idle (simple);
-      g_object_unref (simple);
+      task = g_task_new (resolver, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_resolver_lookup_by_name_async);
+      g_task_return_pointer (task, g_list_append (NULL, addr),
+                             (GDestroyNotify) g_resolver_free_addresses);
+      g_object_unref (task);
       return;
     }
 
@@ -449,12 +448,8 @@ g_resolver_lookup_by_name_finish (GResolver     *resolver,
     return NULL;
   else if (g_async_result_is_tagged (result, g_resolver_lookup_by_name_async))
     {
-      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-      GInetAddress *addr;
-
       /* Handle the stringified-IP-addr case */
-      addr = g_simple_async_result_get_op_res_gpointer (simple);
-      return g_list_append (NULL, g_object_ref (addr));
+      return g_task_propagate_pointer (G_TASK (result), error);
     }
 
   addrs = G_RESOLVER_GET_CLASS (resolver)->
diff --git a/gio/gsocketaddressenumerator.c b/gio/gsocketaddressenumerator.c
index 2193860..35462af 100644
--- a/gio/gsocketaddressenumerator.c
+++ b/gio/gsocketaddressenumerator.c
@@ -22,7 +22,7 @@
 #include "gsocketaddressenumerator.h"
 #include "glibintl.h"
 
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 
 
 G_DEFINE_ABSTRACT_TYPE (GSocketAddressEnumerator, g_socket_address_enumerator, G_TYPE_OBJECT);
@@ -95,21 +95,19 @@ g_socket_address_enumerator_real_next_async (GSocketAddressEnumerator *enumerato
 					     GAsyncReadyCallback       callback,
 					     gpointer                  user_data)
 {
-  GSimpleAsyncResult *result;
+  GTask *task;
   GSocketAddress *address;
   GError *error = NULL;
 
-  result = g_simple_async_result_new (G_OBJECT (enumerator),
-				      callback, user_data,
-				      g_socket_address_enumerator_real_next_async);
+  task = g_task_new (enumerator, NULL, callback, user_data);
+
   address = g_socket_address_enumerator_next (enumerator, cancellable, &error);
-  if (address)
-    g_simple_async_result_set_op_res_gpointer (result, address, NULL);
-  else if (error)
-    g_simple_async_result_take_error (result, error);
+  if (error)
+    g_task_return_error (task, error);
+  else
+    g_task_return_pointer (task, address, g_object_unref);
 
-  g_simple_async_result_complete_in_idle (result);
-  g_object_unref (result);
+  g_object_unref (task);
 }
 
 /**
@@ -144,16 +142,9 @@ g_socket_address_enumerator_real_next_finish (GSocketAddressEnumerator  *enumera
 					      GAsyncResult              *result,
 					      GError                   **error)
 {
-  GSimpleAsyncResult *simple;
+  g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL);
 
-  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
-  simple = G_SIMPLE_ASYNC_RESULT (result);
-  g_return_val_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_address_enumerator_real_next_async, NULL);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-  else
-    return g_simple_async_result_get_op_res_gpointer (simple);
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 /**
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index 8f763be..b90679b 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -34,7 +34,7 @@
 #include <gio/gsocketconnection.h>
 #include <gio/gproxyaddressenumerator.h>
 #include <gio/gproxyaddress.h>
-#include <gio/gsimpleasyncresult.h>
+#include <gio/gtask.h>
 #include <gio/gcancellable.h>
 #include <gio/gioerror.h>
 #include <gio/gsocket.h>
@@ -1271,7 +1271,7 @@ g_socket_client_connect_to_uri (GSocketClient  *client,
 
 typedef struct
 {
-  GSimpleAsyncResult *result;
+  GTask *task;
   GCancellable *cancellable;
   GSocketClient *client;
 
@@ -1286,46 +1286,40 @@ typedef struct
 } GSocketClientAsyncConnectData;
 
 static void
-g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
+g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data)
 {
-  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, data->connection);
+  g_clear_object (&data->cancellable);
+  g_clear_object (&data->connectable);
+  g_clear_object (&data->enumerator);
+  g_clear_object (&data->proxy_addr);
+  g_clear_object (&data->current_addr);
+  g_clear_object (&data->current_socket);
+  g_clear_object (&data->connection);
 
-  if (data->last_error)
-    {
-      g_simple_async_result_take_error (data->result, data->last_error);
-    }
-  else
-    {
-      g_assert (data->connection);
+  g_clear_error (&data->last_error);
 
-      if (!G_IS_SOCKET_CONNECTION (data->connection))
-	{
-	  GSocketConnection *wrapper_connection;
+  g_slice_free (GSocketClientAsyncConnectData, data);
+}
 
-	  wrapper_connection = g_tcp_wrapper_connection_new (data->connection,
-							     data->current_socket);
-	  g_object_unref (data->connection);
-	  data->connection = (GIOStream *)wrapper_connection;
-	}
+static void
+g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
+{
+  g_assert (data->connection);
 
-      g_simple_async_result_set_op_res_gpointer (data->result,
-						 data->connection,
-						 g_object_unref);
+  if (!G_IS_SOCKET_CONNECTION (data->connection))
+    {
+      GSocketConnection *wrapper_connection;
+
+      wrapper_connection = g_tcp_wrapper_connection_new (data->connection,
+                                                         data->current_socket);
+      g_object_unref (data->connection);
+      data->connection = (GIOStream *)wrapper_connection;
     }
 
-  g_simple_async_result_complete (data->result);
-  g_object_unref (data->result);
-  g_object_unref (data->connectable);
-  g_object_unref (data->enumerator);
-  if (data->cancellable)
-    g_object_unref (data->cancellable);
-  if (data->current_addr)
-    g_object_unref (data->current_addr);
-  if (data->current_socket)
-    g_object_unref (data->current_socket);
-  if (data->proxy_addr)
-    g_object_unref (data->proxy_addr);
-  g_slice_free (GSocketClientAsyncConnectData, data);
+  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, data->connection);
+  g_task_return_pointer (data->task, data->connection, g_object_unref);
+  data->connection = NULL;
+  g_object_unref (data->task);
 }
 
 
@@ -1525,28 +1519,34 @@ g_socket_client_enumerator_callback (GObject      *object,
   GSocketClientAsyncConnectData *data = user_data;
   GSocketAddress *address = NULL;
   GSocket *socket;
-  GError *tmp_error = NULL;
+  GError *error = NULL;
 
-  if (g_cancellable_is_cancelled (data->cancellable))
-    {
-      g_clear_error (&data->last_error);
-      g_cancellable_set_error_if_cancelled (data->cancellable, &data->last_error);
-      g_socket_client_async_connect_complete (data);
-      return;
-    }
+  if (g_task_return_error_if_cancelled (data->task))
+    return;
 
   address = g_socket_address_enumerator_next_finish (data->enumerator,
-						     result, &tmp_error);
-
+                                                     result, &error);
   if (address == NULL)
     {
-      if (tmp_error)
-	set_last_error (data, tmp_error);
-      else if (data->last_error == NULL)
-        g_set_error_literal (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                             _("Unknown error on connect"));
-
-      g_socket_client_async_connect_complete (data);
+      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL);
+      if (!error)
+        {
+          if (data->last_error)
+            {
+              error = data->last_error;
+              data->last_error = NULL;
+            }
+          else
+            {
+              g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                   _("Unknown error on connect"));
+            }
+        }
+      if (error)
+        g_task_return_error (data->task, error);
+      else
+        g_task_return_pointer (data->task, NULL, NULL);
+      g_object_unref (data->task);
       return;
     }
 
@@ -1605,16 +1605,9 @@ g_socket_client_connect_async (GSocketClient       *client,
   g_return_if_fail (G_IS_SOCKET_CLIENT (client));
 
   data = g_slice_new0 (GSocketClientAsyncConnectData);
-
-  data->result = g_simple_async_result_new (G_OBJECT (client),
-					    callback, user_data,
-					    g_socket_client_connect_async);
   data->client = client;
   if (cancellable)
     data->cancellable = g_object_ref (cancellable);
-  else
-    data->cancellable = NULL;
-  data->last_error = NULL;
   data->connectable = g_object_ref (connectable);
 
   if (can_use_proxy (client))
@@ -1622,6 +1615,9 @@ g_socket_client_connect_async (GSocketClient       *client,
   else
       data->enumerator = g_socket_connectable_enumerate (connectable);
 
+  data->task = g_task_new (client, cancellable, callback, user_data);
+  g_task_set_task_data (data->task, data, (GDestroyNotify)g_socket_client_async_connect_data_free);
+
   enumerator_next_async (data);
 }
 
@@ -1658,8 +1654,9 @@ g_socket_client_connect_to_host_async (GSocketClient        *client,
 					 &error);
   if (connectable == NULL)
     {
-      g_simple_async_report_take_gerror_in_idle (G_OBJECT (client),
-					    callback, user_data, error);
+      GTask *task = g_task_new (client, NULL, callback, user_data);
+      g_task_return_error (task, error);
+      g_object_unref (task);
     }
   else
     {
@@ -1733,8 +1730,9 @@ g_socket_client_connect_to_uri_async (GSocketClient        *client,
   connectable = g_network_address_parse_uri (uri, default_port, &error);
   if (connectable == NULL)
     {
-      g_simple_async_report_take_gerror_in_idle (G_OBJECT (client),
-					    callback, user_data, error);
+      GTask *task = g_task_new (client, NULL, callback, user_data);
+      g_task_return_error (task, error);
+      g_object_unref (task);
     }
   else
     {
@@ -1764,12 +1762,9 @@ g_socket_client_connect_finish (GSocketClient  *client,
 				GAsyncResult   *result,
 				GError        **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
+  g_return_val_if_fail (g_task_is_valid (result, client), NULL);
 
-  return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 /**
diff --git a/gio/gsocketconnection.c b/gio/gsocketconnection.c
index a881a47..8a6bb59 100644
--- a/gio/gsocketconnection.c
+++ b/gio/gsocketconnection.c
@@ -32,7 +32,7 @@
 #include "gsocketoutputstream.h"
 #include "gsocketinputstream.h"
 #include <gio/giostream.h>
-#include <gio/gsimpleasyncresult.h>
+#include <gio/gtask.h>
 #include "gunixconnection.h"
 #include "gtcpconnection.h"
 #include "glibintl.h"
@@ -184,23 +184,21 @@ g_socket_connection_connect_async (GSocketConnection   *connection,
 				   GAsyncReadyCallback  callback,
 				   gpointer             user_data)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
   GError *tmp_error = NULL;
 
   g_return_if_fail (G_IS_SOCKET_CONNECTION (connection));
   g_return_if_fail (G_IS_SOCKET_ADDRESS (address));
 
-  simple = g_simple_async_result_new (G_OBJECT (connection),
-				      callback, user_data,
-				      g_socket_connection_connect_async);
+  task = g_task_new (connection, cancellable, callback, user_data);
 
   g_socket_set_blocking (connection->priv->socket, FALSE);
 
   if (g_socket_connect (connection->priv->socket, address,
 			cancellable, &tmp_error))
     {
-      g_simple_async_result_set_op_res_gboolean (simple, TRUE);
-      g_simple_async_result_complete_in_idle (simple);
+      g_task_return_boolean (task, TRUE);
+      g_object_unref (task);
     }
   else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
     {
@@ -209,16 +207,14 @@ g_socket_connection_connect_async (GSocketConnection   *connection,
       g_error_free (tmp_error);
       source = g_socket_create_source (connection->priv->socket,
 				       G_IO_OUT, cancellable);
-      g_source_set_callback (source,
-			     (GSourceFunc) g_socket_connection_connect_callback,
-			     simple, NULL);
-      g_source_attach (source, g_main_context_get_thread_default ());
+      g_task_attach_source (task, source,
+                            (GSourceFunc) g_socket_connection_connect_callback);
       g_source_unref (source);
     }
   else
     {
-      g_simple_async_result_take_error (simple, tmp_error);
-      g_simple_async_result_complete_in_idle (simple);
+      g_task_return_error (task, tmp_error);
+      g_object_unref (task);
     }
 }
 
@@ -227,20 +223,16 @@ g_socket_connection_connect_callback (GSocket      *socket,
 				      GIOCondition  condition,
 				      gpointer      user_data)
 {
-  GSimpleAsyncResult *simple = user_data;
-  GSocketConnection *connection;
+  GTask *task = user_data;
+  GSocketConnection *connection = g_task_get_source_object (task);
   GError *error = NULL;
 
-  connection = G_SOCKET_CONNECTION (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
-  g_object_unref (connection);
-
   if (g_socket_check_connect_result (connection->priv->socket, &error))
-    g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+    g_task_return_boolean (task, TRUE);
   else
-    g_simple_async_result_take_error (simple, error);
+    g_task_return_error (task, error);
 
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
+  g_object_unref (task);
   return FALSE;
 }
 
@@ -261,15 +253,10 @@ g_socket_connection_connect_finish (GSocketConnection  *connection,
 				    GAsyncResult       *result,
 				    GError            **error)
 {
-  GSimpleAsyncResult *simple;
-
   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
-  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), g_socket_connection_connect_async), FALSE);
+  g_return_val_if_fail (g_task_is_valid (result, connection), FALSE);
 
-  simple = G_SIMPLE_ASYNC_RESULT (result);
-  if (g_simple_async_result_propagate_error (simple, error))
-    return FALSE;
-  return TRUE;
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 /**
@@ -479,29 +466,23 @@ g_socket_connection_close_async (GIOStream           *stream,
 				 GAsyncReadyCallback  callback,
 				 gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   GIOStreamClass *class;
   GError *error;
 
   class = G_IO_STREAM_GET_CLASS (stream);
 
+  task = g_task_new (stream, cancellable, callback, user_data);
+
   /* socket close is not blocked, just do it! */
   error = NULL;
   if (class->close_fn &&
       !class->close_fn (stream, cancellable, &error))
-    {
-      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
-					    callback, user_data,
-					    error);
-      return;
-    }
+    g_task_return_error (task, error);
+  else
+    g_task_return_boolean (task, TRUE);
 
-  res = g_simple_async_result_new (G_OBJECT (stream),
-				   callback,
-				   user_data,
-				   g_socket_connection_close_async);
-  g_simple_async_result_complete_in_idle (res);
-  g_object_unref (res);
+  g_object_unref (task);
 }
 
 static gboolean
@@ -509,7 +490,7 @@ g_socket_connection_close_finish (GIOStream     *stream,
 				  GAsyncResult  *result,
 				  GError       **error)
 {
-  return TRUE;
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 typedef struct {
diff --git a/gio/gsocketinputstream.c b/gio/gsocketinputstream.c
index 89e8a84..077d949 100644
--- a/gio/gsocketinputstream.c
+++ b/gio/gsocketinputstream.c
@@ -27,7 +27,7 @@
 #include "gsocketinputstream.h"
 #include "glibintl.h"
 
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gcancellable.h"
 #include "gpollableinputstream.h"
 #include "gioerror.h"
@@ -62,8 +62,6 @@ struct _GSocketInputStreamPrivate
   GSocket *socket;
 
   /* pending operation metadata */
-  GSimpleAsyncResult *result;
-  GCancellable *cancellable;
   gpointer buffer;
   gsize count;
 };
diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c
index 970540a..c7444ef 100644
--- a/gio/gsocketlistener.c
+++ b/gio/gsocketlistener.c
@@ -28,7 +28,7 @@
 #include "config.h"
 #include "gsocketlistener.h"
 
-#include <gio/gsimpleasyncresult.h>
+#include <gio/gtask.h>
 #include <gio/gcancellable.h>
 #include <gio/gsocketaddress.h>
 #include <gio/ginetaddress.h>
@@ -681,43 +681,32 @@ g_socket_listener_accept (GSocketListener  *listener,
   return connection;
 }
 
-struct AcceptAsyncData {
-  GSimpleAsyncResult *simple;
-  GCancellable *cancellable;
-  GList *sources;
-};
-
 static gboolean
 accept_ready (GSocket      *accept_socket,
-	      GIOCondition  condition,
-	      gpointer      _data)
+              GIOCondition  condition,
+              gpointer      user_data)
 {
-  struct AcceptAsyncData *data = _data;
+  GTask *task = user_data;
   GError *error = NULL;
   GSocket *socket;
   GObject *source_object;
 
-  socket = g_socket_accept (accept_socket, data->cancellable, &error);
+  socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error);
   if (socket)
     {
-      g_simple_async_result_set_op_res_gpointer (data->simple, socket,
-						 g_object_unref);
+      g_task_return_pointer (task, socket, g_object_unref);
       source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
       if (source_object)
-	g_object_set_qdata_full (G_OBJECT (data->simple),
-				 source_quark,
-				 g_object_ref (source_object), g_object_unref);
+        g_object_set_qdata_full (G_OBJECT (task),
+                                 source_quark,
+                                 g_object_ref (source_object), g_object_unref);
     }
   else
     {
-      g_simple_async_result_take_error (data->simple, error);
+      g_task_return_error (task, error);
     }
 
-  g_simple_async_result_complete_in_idle (data->simple);
-  g_object_unref (data->simple);
-  free_sources (data->sources);
-  g_free (data);
-
+  g_object_unref (task);
   return FALSE;
 }
 
@@ -742,27 +731,25 @@ g_socket_listener_accept_socket_async (GSocketListener     *listener,
 				       GAsyncReadyCallback  callback,
 				       gpointer             user_data)
 {
-  struct AcceptAsyncData *data;
+  GTask *task;
+  GList *sources;
   GError *error = NULL;
 
+  task = g_task_new (listener, cancellable, callback, user_data);
+
   if (!check_listener (listener, &error))
     {
-      g_simple_async_report_take_gerror_in_idle (G_OBJECT (listener),
-					    callback, user_data,
-					    error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
-  data = g_new0 (struct AcceptAsyncData, 1);
-  data->simple = g_simple_async_result_new (G_OBJECT (listener),
-					    callback, user_data,
-					    g_socket_listener_accept_socket_async);
-  data->cancellable = cancellable;
-  data->sources = add_sources (listener,
-			       accept_ready,
-			       data,
-			       cancellable,
-			       g_main_context_get_thread_default ());
+  sources = add_sources (listener,
+                         accept_ready,
+                         task,
+                         cancellable,
+                         g_main_context_get_thread_default ());
+  g_task_set_task_data (task, sources, (GDestroyNotify) free_sources);
 }
 
 /**
@@ -785,24 +772,13 @@ g_socket_listener_accept_socket_finish (GSocketListener  *listener,
 					GObject         **source_object,
 					GError          **error)
 {
-  GSocket *socket;
-  GSimpleAsyncResult *simple;
-
   g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
-
-  simple = G_SIMPLE_ASYNC_RESULT (result);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_listener_accept_socket_async);
-
-  socket = g_simple_async_result_get_op_res_gpointer (simple);
+  g_return_val_if_fail (g_task_is_valid (result, listener), NULL);
 
   if (source_object)
     *source_object = g_object_get_qdata (G_OBJECT (result), source_quark);
 
-  return g_object_ref (socket);
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 /**
diff --git a/gio/gsocketoutputstream.c b/gio/gsocketoutputstream.c
index 145f009..688ebee 100644
--- a/gio/gsocketoutputstream.c
+++ b/gio/gsocketoutputstream.c
@@ -29,7 +29,7 @@
 #include "gsocket.h"
 #include "glibintl.h"
 
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gcancellable.h"
 #include "gpollableinputstream.h"
 #include "gpollableoutputstream.h"
@@ -66,8 +66,6 @@ struct _GSocketOutputStreamPrivate
   GSocket *socket;
 
   /* pending operation metadata */
-  GSimpleAsyncResult *result;
-  GCancellable *cancellable;
   gconstpointer buffer;
   gsize count;
 };
diff --git a/gio/gsocks4aproxy.c b/gio/gsocks4aproxy.c
index ff84151..e9b00f3 100644
--- a/gio/gsocks4aproxy.c
+++ b/gio/gsocks4aproxy.c
@@ -26,7 +26,6 @@
 
 #include <string.h>
 
-#include "gasyncresult.h"
 #include "giomodule.h"
 #include "giomodule-priv.h"
 #include "giostream.h"
@@ -36,7 +35,7 @@
 #include "goutputstream.h"
 #include "gproxy.h"
 #include "gproxyaddress.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 
 #define SOCKS4_VERSION		  4
 
@@ -249,10 +248,7 @@ error:
 
 typedef struct
 {
-  GSimpleAsyncResult *simple;
   GIOStream *io_stream;
-  GProxyAddress *proxy_address;
-  GCancellable *cancellable;
 
   /* For connecting */
   guint8 *buffer;
@@ -271,50 +267,34 @@ static void connect_reply_read_cb     (GObject          *source,
 static void
 free_connect_data (ConnectAsyncData *data)
 {
-  if (data->io_stream)
-    g_object_unref (data->io_stream);
-  
-  if (data->proxy_address)
-    g_object_unref (data->proxy_address);
-
-  if (data->cancellable)
-    g_object_unref (data->cancellable);
-
+  g_object_unref (data->io_stream);
   g_slice_free (ConnectAsyncData, data);
 }
 
 static void
-complete_async_from_error (ConnectAsyncData *data, GError *error)
-{
-  GSimpleAsyncResult *simple = data->simple;
-  g_simple_async_result_take_error (data->simple, error);
-  g_simple_async_result_set_op_res_gpointer (simple, NULL, NULL);
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
-}
-
-static void
-do_read (GAsyncReadyCallback callback, ConnectAsyncData *data)
+do_read (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data)
 {
    GInputStream *in;
    in = g_io_stream_get_input_stream (data->io_stream);
    g_input_stream_read_async (in,
 			      data->buffer + data->offset,
 			      data->length - data->offset,
-			      G_PRIORITY_DEFAULT, data->cancellable,
-			      callback, data);
+			      g_task_get_priority (task),
+			      g_task_get_cancellable (task),
+			      callback, task);
 }
 
 static void
-do_write (GAsyncReadyCallback callback, ConnectAsyncData *data)
+do_write (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data)
 {
   GOutputStream *out;
   out = g_io_stream_get_output_stream (data->io_stream);
   g_output_stream_write_async (out,
 			       data->buffer + data->offset,
 			       data->length - data->offset,
-			       G_PRIORITY_DEFAULT, data->cancellable,
-			       callback, data);
+			       g_task_get_priority (task),
+			       g_task_get_cancellable (task),
+			       callback, task);
 }
 
 
@@ -328,26 +308,17 @@ g_socks4a_proxy_connect_async (GProxy               *proxy,
 			       gpointer              user_data)
 {
   GError *error = NULL;
-  GSimpleAsyncResult *simple;
+  GTask *task;
   ConnectAsyncData *data;
   const gchar *hostname;
   guint16 port;
   const gchar *username;
 
-  simple = g_simple_async_result_new (G_OBJECT (proxy),
-				      callback, user_data,
-				      g_socks4a_proxy_connect_async);
-
   data = g_slice_new0 (ConnectAsyncData);
-
-  data->simple = simple;
   data->io_stream = g_object_ref (io_stream);
 
-  if (cancellable)
-    data->cancellable = g_object_ref (cancellable);
-
-  g_simple_async_result_set_op_res_gpointer (simple, data, 
-					     (GDestroyNotify) free_connect_data);
+  task = g_task_new (proxy, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify) free_connect_data);
 
   hostname = g_proxy_address_get_destination_hostname (proxy_address);
   port = g_proxy_address_get_destination_port (proxy_address);
@@ -361,14 +332,12 @@ g_socks4a_proxy_connect_async (GProxy               *proxy,
 
   if (data->length < 0)
     {
-      g_simple_async_result_take_error (data->simple, error);
-      g_simple_async_result_set_op_res_gpointer (simple, NULL, NULL);
-      g_simple_async_result_complete_in_idle (simple);
-      g_object_unref (simple);
+      g_task_return_error (task, error);
+      g_object_unref (task);
     }
   else
     {
-      do_write (connect_msg_write_cb, data);
+      do_write (connect_msg_write_cb, task, data);
     }
 }
 
@@ -377,8 +346,9 @@ connect_msg_write_cb (GObject      *source,
 		      GAsyncResult *result,
 		      gpointer      user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize written;
 
   written = g_output_stream_write_finish (G_OUTPUT_STREAM (source),
@@ -386,7 +356,8 @@ connect_msg_write_cb (GObject      *source,
   
   if (written < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -400,11 +371,11 @@ connect_msg_write_cb (GObject      *source,
       data->length = SOCKS4_CONN_REP_LEN;
       data->offset = 0;
 
-      do_read (connect_reply_read_cb, data);
+      do_read (connect_reply_read_cb, task, data);
     }
   else
     {
-      do_write (connect_msg_write_cb, data);
+      do_write (connect_msg_write_cb, task, data);
     }
 }
 
@@ -413,8 +384,9 @@ connect_reply_read_cb (GObject       *source,
 		       GAsyncResult  *result,
 		       gpointer       user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize read;
 
   read = g_input_stream_read_finish (G_INPUT_STREAM (source),
@@ -422,7 +394,8 @@ connect_reply_read_cb (GObject       *source,
 
   if (read < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -432,18 +405,20 @@ connect_reply_read_cb (GObject       *source,
     {
       if (!parse_connect_reply (data->buffer, &error))
 	{
-	  complete_async_from_error (data, error);
+	  g_task_return_error (task, error);
+	  g_object_unref (task);
+	  return;
 	}
       else
 	{
-	  GSimpleAsyncResult *simple = data->simple;
-	  g_simple_async_result_complete (simple);
-	  g_object_unref (simple);
+	  g_task_return_pointer (task, g_object_ref (data->io_stream), g_object_unref);
+	  g_object_unref (task);
+	  return;
 	}
     }
   else
     {
-      do_read (connect_reply_read_cb, data);
+      do_read (connect_reply_read_cb, task, data);
     }
 }
 
@@ -456,13 +431,7 @@ g_socks4a_proxy_connect_finish (GProxy       *proxy,
 			        GAsyncResult *result,
 			        GError      **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-  ConnectAsyncData *data = g_simple_async_result_get_op_res_gpointer (simple);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-
-  return g_object_ref (data->io_stream);
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 static gboolean
diff --git a/gio/gsocks5proxy.c b/gio/gsocks5proxy.c
index 2dac977..9d9055f 100644
--- a/gio/gsocks5proxy.c
+++ b/gio/gsocks5proxy.c
@@ -39,7 +39,7 @@
 #include "goutputstream.h"
 #include "gproxy.h"
 #include "gproxyaddress.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 
 #define SOCKS5_VERSION		  0x05
 
@@ -538,7 +538,6 @@ error:
 
 typedef struct
 {
-  GSimpleAsyncResult *simple;
   GIOStream *io_stream;
   gchar *hostname;
   guint16 port;
@@ -547,7 +546,6 @@ typedef struct
   guint8 *buffer;
   gssize length;
   gssize offset;
-  GCancellable *cancellable;
 } ConnectAsyncData;
 
 static void nego_msg_write_cb	      (GObject          *source,
@@ -562,7 +560,7 @@ static void auth_msg_write_cb	      (GObject          *source,
 static void auth_reply_read_cb	      (GObject          *source,
 				       GAsyncResult     *result,
 				       gpointer          user_data);
-static void send_connect_msg	      (ConnectAsyncData *data);
+static void send_connect_msg	      (GTask            *task);
 static void connect_msg_write_cb      (GObject          *source,
 				       GAsyncResult     *result,
 				       gpointer          user_data);
@@ -579,52 +577,40 @@ static void connect_addr_read_cb      (GObject          *source,
 static void
 free_connect_data (ConnectAsyncData *data)
 {
-  if (data->io_stream)
-    g_object_unref (data->io_stream);
+  g_object_unref (data->io_stream);
 
   g_free (data->hostname);
   g_free (data->username);
   g_free (data->password);
   g_free (data->buffer);
-  
-  if (data->cancellable)
-    g_object_unref (data->cancellable);
 
   g_slice_free (ConnectAsyncData, data);
 }
 
 static void
-complete_async_from_error (ConnectAsyncData *data, GError *error)
-{
-  GSimpleAsyncResult *simple = data->simple;
-  g_simple_async_result_take_error (data->simple, error);
-  g_simple_async_result_set_op_res_gpointer (simple, NULL, NULL);
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
-}
-
-static void
-do_read (GAsyncReadyCallback callback, ConnectAsyncData *data)
+do_read (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data)
 {
    GInputStream *in;
    in = g_io_stream_get_input_stream (data->io_stream);
    g_input_stream_read_async (in,
 			      data->buffer + data->offset,
 			      data->length - data->offset,
-			      G_PRIORITY_DEFAULT, data->cancellable,
-			      callback, data);
+			      g_task_get_priority (task),
+			      g_task_get_cancellable (task),
+			      callback, task);
 }
 
 static void
-do_write (GAsyncReadyCallback callback, ConnectAsyncData *data)
+do_write (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data)
 {
   GOutputStream *out;
   out = g_io_stream_get_output_stream (data->io_stream);
   g_output_stream_write_async (out,
 			       data->buffer + data->offset,
 			       data->length - data->offset,
-			       G_PRIORITY_DEFAULT, data->cancellable,
-			       callback, data);
+			       g_task_get_priority (task),
+			       g_task_get_cancellable (task),
+			       callback, task);
 }
 
 static void
@@ -635,20 +621,14 @@ g_socks5_proxy_connect_async (GProxy               *proxy,
 			      GAsyncReadyCallback   callback,
 			      gpointer              user_data)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
   ConnectAsyncData *data;
 
-  simple = g_simple_async_result_new (G_OBJECT (proxy),
-				      callback, user_data,
-				      g_socks5_proxy_connect_async);
-
   data = g_slice_new0 (ConnectAsyncData);
-
-  data->simple = simple;
   data->io_stream = g_object_ref (io_stream);
 
-  if (cancellable)
-    data->cancellable = g_object_ref (cancellable);
+  task = g_task_new (proxy, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify) free_connect_data);
 
   g_object_get (G_OBJECT (proxy_address),
 		"destination-hostname", &data->hostname,
@@ -657,15 +637,12 @@ g_socks5_proxy_connect_async (GProxy               *proxy,
 		"password", &data->password,
 		NULL);
 
-  g_simple_async_result_set_op_res_gpointer (simple, data, 
-					     (GDestroyNotify) free_connect_data);
-
   data->buffer = g_malloc0 (SOCKS5_NEGO_MSG_LEN);
   data->length = set_nego_msg (data->buffer,
 			       data->username || data->password);
   data->offset = 0;
 
-  do_write (nego_msg_write_cb, data);
+  do_write (nego_msg_write_cb, task, data);
 }
 
 
@@ -674,8 +651,9 @@ nego_msg_write_cb (GObject      *source,
 		   GAsyncResult *res,
 		   gpointer      user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize written;
 
   written = g_output_stream_write_finish (G_OUTPUT_STREAM (source),
@@ -683,7 +661,8 @@ nego_msg_write_cb (GObject      *source,
 
   if (written < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -697,11 +676,11 @@ nego_msg_write_cb (GObject      *source,
       data->length = SOCKS5_NEGO_REP_LEN;
       data->offset = 0;
 
-      do_read (nego_reply_read_cb, data);
+      do_read (nego_reply_read_cb, task, data);
     }
   else
     {
-      do_write (nego_msg_write_cb, data);
+      do_write (nego_msg_write_cb, task, data);
     }
 }
 
@@ -710,8 +689,9 @@ nego_reply_read_cb (GObject      *source,
 		    GAsyncResult *res,
 		    gpointer      user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize read;
 
   read = g_input_stream_read_finish (G_INPUT_STREAM (source),
@@ -719,7 +699,8 @@ nego_reply_read_cb (GObject      *source,
 
   if (read < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -733,7 +714,8 @@ nego_reply_read_cb (GObject      *source,
 
       if (!parse_nego_reply (data->buffer, has_auth, &must_auth, &error))
 	{
-	  complete_async_from_error (data, error);
+	  g_task_return_error (task, error);
+	  g_object_unref (task);
 	  return;
 	}
 
@@ -750,20 +732,21 @@ nego_reply_read_cb (GObject      *source,
 
 	  if (data->length < 0)
 	    {
-	      complete_async_from_error (data, error);
+	      g_task_return_error (task, error);
+	      g_object_unref (task);
 	      return;
 	    }
 	  
-	  do_write (auth_msg_write_cb, data);
+	  do_write (auth_msg_write_cb, task, data);
 	}
       else
 	{
-	  send_connect_msg (data);
+	  send_connect_msg (task);
 	}
     }
   else
     {
-      do_read (nego_reply_read_cb, data);
+      do_read (nego_reply_read_cb, task, data);
     }
 }
 
@@ -772,8 +755,9 @@ auth_msg_write_cb (GObject      *source,
 		   GAsyncResult *result,
 		   gpointer      user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize written;
 
   written = g_output_stream_write_finish (G_OUTPUT_STREAM (source),
@@ -781,7 +765,8 @@ auth_msg_write_cb (GObject      *source,
   
   if (written < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -795,11 +780,11 @@ auth_msg_write_cb (GObject      *source,
       data->length = SOCKS5_NEGO_REP_LEN;
       data->offset = 0;
 
-      do_read (auth_reply_read_cb, data);
+      do_read (auth_reply_read_cb, task, data);
     }
   else
     {
-      do_write (auth_msg_write_cb, data);
+      do_write (auth_msg_write_cb, task, data);
     }
 }
 
@@ -808,8 +793,9 @@ auth_reply_read_cb (GObject      *source,
 		    GAsyncResult *result,
 		    gpointer      user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize read;
 
   read = g_input_stream_read_finish (G_INPUT_STREAM (source),
@@ -817,7 +803,8 @@ auth_reply_read_cb (GObject      *source,
 
   if (read < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -827,21 +814,23 @@ auth_reply_read_cb (GObject      *source,
     {
       if (!check_auth_status (data->buffer, &error))
 	{
-	  complete_async_from_error (data, error);
+	  g_task_return_error (task, error);
+	  g_object_unref (task);
 	  return;
 	}
 	
-      send_connect_msg (data);
+      send_connect_msg (task);
     }
   else
     {
-      do_read (auth_reply_read_cb, data);
+      do_read (auth_reply_read_cb, task, data);
     }
 }
 
 static void
-send_connect_msg (ConnectAsyncData *data)
+send_connect_msg (GTask *task)
 {
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
 
   g_free (data->buffer);
@@ -855,11 +844,12 @@ send_connect_msg (ConnectAsyncData *data)
   
   if (data->length < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
-  do_write (connect_msg_write_cb, data);
+  do_write (connect_msg_write_cb, task, data);
 }
 
 static void
@@ -867,8 +857,9 @@ connect_msg_write_cb (GObject      *source,
 		      GAsyncResult *result,
 		      gpointer      user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize written;
 
   written = g_output_stream_write_finish (G_OUTPUT_STREAM (source),
@@ -876,7 +867,8 @@ connect_msg_write_cb (GObject      *source,
   
   if (written < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -890,11 +882,11 @@ connect_msg_write_cb (GObject      *source,
       data->length = 4;
       data->offset = 0;
 
-      do_read (connect_reply_read_cb, data);
+      do_read (connect_reply_read_cb, task, data);
     }
   else
     {
-      do_write (connect_msg_write_cb, data);
+      do_write (connect_msg_write_cb, task, data);
     }
 }
 
@@ -903,8 +895,9 @@ connect_reply_read_cb (GObject       *source,
 		       GAsyncResult  *result,
 		       gpointer       user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize read;
 
   read = g_input_stream_read_finish (G_INPUT_STREAM (source),
@@ -912,7 +905,8 @@ connect_reply_read_cb (GObject       *source,
 
   if (read < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -924,7 +918,8 @@ connect_reply_read_cb (GObject       *source,
 
       if (!parse_connect_reply (data->buffer, &atype, &error))
 	{
-	  complete_async_from_error (data, error);
+	  g_task_return_error (task, error);
+	  g_object_unref (task);
 	  return;
 	}
 
@@ -933,25 +928,25 @@ connect_reply_read_cb (GObject       *source,
 	  case SOCKS5_ATYP_IPV4:
 	    data->length = 6;
 	    data->offset = 0;
-	    do_read (connect_addr_read_cb, data);
+	    do_read (connect_addr_read_cb, task, data);
 	    break;
 
 	  case SOCKS5_ATYP_IPV6:
 	    data->length = 18;
 	    data->offset = 0;
-	    do_read (connect_addr_read_cb, data);
+	    do_read (connect_addr_read_cb, task, data);
 	    break;
 
 	  case SOCKS5_ATYP_DOMAINNAME:
 	    data->length = 1;
 	    data->offset = 0;
-	    do_read (connect_addr_len_read_cb, data);
+	    do_read (connect_addr_len_read_cb, task, data);
 	    break;
 	}
     }
   else
     {
-      do_read (connect_reply_read_cb, data);
+      do_read (connect_reply_read_cb, task, data);
     }
 }
 
@@ -960,8 +955,9 @@ connect_addr_len_read_cb (GObject      *source,
 			  GAsyncResult *result,
 			  gpointer      user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize read;
 
   read = g_input_stream_read_finish (G_INPUT_STREAM (source),
@@ -969,14 +965,15 @@ connect_addr_len_read_cb (GObject      *source,
 
   if (read < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
   data->length = data->buffer[0] + 2;
   data->offset = 0;
 
-  do_read (connect_addr_read_cb, data);
+  do_read (connect_addr_read_cb, task, data);
 }
 
 static void
@@ -984,8 +981,9 @@ connect_addr_read_cb (GObject      *source,
 		      GAsyncResult *result,
 		      gpointer      user_data)
 {
+  GTask *task = user_data;
+  ConnectAsyncData *data = g_task_get_task_data (task);
   GError *error = NULL;
-  ConnectAsyncData *data = user_data;
   gssize read;
 
   read = g_input_stream_read_finish (G_INPUT_STREAM (source),
@@ -993,7 +991,8 @@ connect_addr_read_cb (GObject      *source,
 
   if (read < 0)
     {
-      complete_async_from_error (data, error);
+      g_task_return_error (task, error);
+      g_object_unref (task);
       return;
     }
 
@@ -1001,13 +1000,13 @@ connect_addr_read_cb (GObject      *source,
 
   if (data->offset == data->length)
     {
-      GSimpleAsyncResult *simple = data->simple;
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
+      g_task_return_pointer (task, g_object_ref (data->io_stream), g_object_unref);
+      g_object_unref (task);
+      return;
     }
   else
     {
-      do_read (connect_reply_read_cb, data);
+      do_read (connect_reply_read_cb, task, data);
     }
 }
 
@@ -1016,13 +1015,7 @@ g_socks5_proxy_connect_finish (GProxy       *proxy,
 			       GAsyncResult *result,
 			       GError      **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-  ConnectAsyncData *data = g_simple_async_result_get_op_res_gpointer (simple);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return NULL;
-
-  return g_object_ref (data->io_stream);
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 static gboolean
diff --git a/gio/gtcpconnection.c b/gio/gtcpconnection.c
index 69881f6..327ade8 100644
--- a/gio/gtcpconnection.c
+++ b/gio/gtcpconnection.c
@@ -25,7 +25,7 @@
 #include "config.h"
 #include "gtcpconnection.h"
 #include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "giostream.h"
 #include "glibintl.h"
 
@@ -194,76 +194,43 @@ g_tcp_connection_close (GIOStream     *stream,
     ->close_fn (stream, cancellable, error) && !had_error;
 }
 
-typedef struct {
-  GSimpleAsyncResult *res;
-  GCancellable *cancellable;
-} CloseAsyncData;
-
-static void
-close_async_data_free (CloseAsyncData *data)
-{
-  g_object_unref (data->res);
-  if (data->cancellable)
-    g_object_unref (data->cancellable);
-  g_free (data);
-}
-
-static void
-async_close_finish (CloseAsyncData *data,
-                    GError         *error /* consumed */,
-                    gboolean        in_mainloop)
-{
-  GIOStreamClass *parent = G_IO_STREAM_CLASS (g_tcp_connection_parent_class);
-  GIOStream *stream;
-  GError *my_error;
-
-  stream = G_IO_STREAM (g_async_result_get_source_object (G_ASYNC_RESULT (data->res)));
-
-  /* Doesn't block, ignore error */
-  if (error)
-    {
-      parent->close_fn (stream, data->cancellable, NULL);
-      g_simple_async_result_take_error (data->res, error);
-    }
-  else
-    {
-      my_error = NULL;
-      parent->close_fn (stream, data->cancellable, &my_error);
-      if (my_error)
-        g_simple_async_result_take_error (data->res, my_error);
-    }
-
-  if (in_mainloop)
-    g_simple_async_result_complete (data->res);
-  else
-    g_simple_async_result_complete_in_idle (data->res);
-}
-
 static gboolean
 close_read_ready (GSocket        *socket,
 		  GIOCondition    condition,
-		  CloseAsyncData *data)
+		  GTask          *task)
 {
   GError *error = NULL;
   char buffer[1024];
   gssize ret;
 
   ret = g_socket_receive (socket,  buffer, sizeof (buffer),
-			  data->cancellable, &error);
+			  g_task_get_cancellable (task), &error);
   if (ret < 0)
     {
       if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
-	g_error_free (error);
+	{
+	  g_error_free (error);
+	  return TRUE;
+	}
       else
 	{
-	  async_close_finish (data, error, TRUE);
+	  g_task_return_error (task, error);
+	  g_object_unref (task);
 	  return FALSE;
 	}
     }
 
   if (ret == 0)
     {
-      async_close_finish (data, NULL, TRUE);
+      GIOStreamClass *parent = G_IO_STREAM_CLASS (g_tcp_connection_parent_class);
+      GIOStream *stream = g_task_get_source_object (task);;
+
+      parent->close_fn (stream, g_task_get_cancellable (task), &error);
+      if (error)
+        g_task_return_error (task, error);
+      else
+        g_task_return_boolean (task, TRUE);
+
       return FALSE;
     }
 
@@ -279,38 +246,29 @@ g_tcp_connection_close_async (GIOStream           *stream,
 			      gpointer             user_data)
 {
   GTcpConnection *connection = G_TCP_CONNECTION (stream);
-  CloseAsyncData *data;
   GSocket *socket;
   GSource *source;
   GError *error;
+  GTask *task;
 
   if (connection->priv->graceful_disconnect &&
       !g_cancellable_is_cancelled (cancellable) /* Cancelled -> close fast */)
     {
-      data = g_new (CloseAsyncData, 1);
-      data->res =
-	g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
-				   g_tcp_connection_close_async);
-      if (cancellable)
-	data->cancellable = g_object_ref (cancellable);
-      else
-	data->cancellable = NULL;
+      task = g_task_new (stream, cancellable, callback, user_data);
+      g_task_set_priority (task, io_priority);
 
       socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream));
 
       error = NULL;
       if (!g_socket_shutdown (socket, FALSE, TRUE, &error))
 	{
-	  async_close_finish (data, error, FALSE);
-	  close_async_data_free (data);
+	  g_task_return_error (task, error);
+	  g_object_unref (task);
 	  return;
 	}
 
       source = g_socket_create_source (socket, G_IO_IN, cancellable);
-      g_source_set_callback (source,
-			     (GSourceFunc) close_read_ready,
-			     data, (GDestroyNotify)close_async_data_free);
-      g_source_attach (source, g_main_context_get_thread_default ());
+      g_task_attach_source (task, source, (GSourceFunc) close_read_ready);
       g_source_unref (source);
 
       return;
diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c
index b0ac143..3d65d29 100644
--- a/gio/gunixconnection.c
+++ b/gio/gunixconnection.c
@@ -359,18 +359,20 @@ g_unix_connection_send_credentials (GUnixConnection      *connection,
 }
 
 static void
-send_credentials_async_thread (GSimpleAsyncResult *result,
-                               GObject            *object,
-                               GCancellable       *cancellable)
+send_credentials_async_thread (GTask         *task,
+                               gpointer       source_object,
+                               gpointer       task_data,
+                               GCancellable  *cancellable)
 {
   GError *error = NULL;
 
-  if (!g_unix_connection_send_credentials (G_UNIX_CONNECTION (object),
-                                           cancellable,
-                                           &error))
-    {
-      g_simple_async_result_take_error (result, error);
-    }
+  if (g_unix_connection_send_credentials (G_UNIX_CONNECTION (source_object),
+                                          cancellable,
+                                          &error))
+    g_task_return_boolean (task, TRUE);
+  else
+    g_task_return_error (task, error);
+  g_object_unref (task);
 }
 
 /**
@@ -396,17 +398,11 @@ g_unix_connection_send_credentials_async (GUnixConnection      *connection,
                                           GAsyncReadyCallback   callback,
                                           gpointer              user_data)
 {
-  GSimpleAsyncResult *result;
+  GTask *task;
 
-  result = g_simple_async_result_new (G_OBJECT (connection),
-                                      callback, user_data,
-                                      g_unix_connection_send_credentials_async);
+  task = g_task_new (connection, cancellable, callback, user_data);
 
-  g_simple_async_result_run_in_thread (result,
-                                       send_credentials_async_thread,
-                                       G_PRIORITY_DEFAULT,
-                                       cancellable);
-  g_object_unref (result);
+  g_task_run_in_thread (task, send_credentials_async_thread);
 }
 
 /**
@@ -427,18 +423,9 @@ g_unix_connection_send_credentials_finish (GUnixConnection *connection,
                                            GAsyncResult    *result,
                                            GError         **error)
 {
-  g_return_val_if_fail (
-      g_simple_async_result_is_valid (result,
-                                      G_OBJECT (connection),
-                                      g_unix_connection_send_credentials_async),
-      FALSE);
-
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                             error))
-    return FALSE;
-
+  g_return_val_if_fail (g_task_is_valid (result, connection), FALSE);
 
-  return TRUE;
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 /**
@@ -644,21 +631,22 @@ g_unix_connection_receive_credentials (GUnixConnection      *connection,
 }
 
 static void
-receive_credentials_async_thread (GSimpleAsyncResult *result,
-                                  GObject            *object,
-                                  GCancellable       *cancellable)
+receive_credentials_async_thread (GTask         *task,
+                                  gpointer       source_object,
+                                  gpointer       task_data,
+                                  GCancellable  *cancellable)
 {
   GCredentials *creds;
   GError *error = NULL;
 
-  creds = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (object),
+  creds = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (source_object),
                                                  cancellable,
                                                  &error);
-
-  if (creds == NULL)
-    g_simple_async_result_take_error (result, error);
+  if (creds)
+    g_task_return_pointer (task, creds, g_object_unref);
   else
-    g_simple_async_result_set_op_res_gpointer (result, creds, g_object_unref);
+    g_task_return_error (task, error);
+  g_object_unref (task);
 }
 
 /**
@@ -684,18 +672,11 @@ g_unix_connection_receive_credentials_async (GUnixConnection      *connection,
                                               GAsyncReadyCallback   callback,
                                               gpointer              user_data)
 {
-  GSimpleAsyncResult *result;
+  GTask *task;
 
-  result = g_simple_async_result_new (G_OBJECT (connection),
-                                      callback, user_data,
-                                      g_unix_connection_receive_credentials_async);
+  task = g_task_new (connection, cancellable, callback, user_data);
 
-  g_simple_async_result_run_in_thread (result,
-                                       receive_credentials_async_thread,
-                                       G_PRIORITY_DEFAULT,
-                                       cancellable);
-
-  g_object_unref (result);
+  g_task_run_in_thread (task, receive_credentials_async_thread);
 }
 
 /**
@@ -717,16 +698,7 @@ g_unix_connection_receive_credentials_finish (GUnixConnection *connection,
                                               GAsyncResult    *result,
                                               GError         **error)
 {
-  g_return_val_if_fail (
-      g_simple_async_result_is_valid (result,
-                                      G_OBJECT (connection),
-                                      g_unix_connection_receive_credentials_async),
-      NULL);
-
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                             error))
-    return NULL;
-
-  return g_object_ref (g_simple_async_result_get_op_res_gpointer (
-      G_SIMPLE_ASYNC_RESULT (result)));
+  g_return_val_if_fail (g_task_is_valid (result, connection), NULL);
+
+  return g_task_propagate_pointer (G_TASK (result), error);
 }



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