[glib] gio: (belatedly) port gdbus from GSimpleAsyncResult to GTask



commit f10b6550ff2ce55d06b92d6dc3e443fc007b2f7a
Author: Dan Winship <danw gnome org>
Date:   Thu Aug 2 15:46:32 2012 -0400

    gio: (belatedly) port gdbus from GSimpleAsyncResult to GTask
    
    https://bugzilla.gnome.org/show_bug.cgi?id=661767

 gio/gdbusaddress.c    |   79 ++++------
 gio/gdbusconnection.c |  431 +++++++++++++++++--------------------------------
 gio/gdbusprivate.c    |  197 +++++++++--------------
 gio/gdbusprivate.h    |    3 +-
 gio/gdbusproxy.c      |  266 ++++++++++++------------------
 5 files changed, 367 insertions(+), 609 deletions(-)
---
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index 6d17b7c..5e58065 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -34,7 +34,7 @@
 #include "gsocketclient.h"
 #include "giostream.h"
 #include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "glib-private.h"
 #include "gdbusprivate.h"
 #include "giomodule-priv.h"
@@ -794,7 +794,6 @@ out:
 
 typedef struct {
   gchar *address;
-  GIOStream *stream;
   gchar *guid;
 } GetStreamData;
 
@@ -802,29 +801,28 @@ static void
 get_stream_data_free (GetStreamData *data)
 {
   g_free (data->address);
-  if (data->stream != NULL)
-    g_object_unref (data->stream);
   g_free (data->guid);
   g_free (data);
 }
 
 static void
-get_stream_thread_func (GSimpleAsyncResult *res,
-                        GObject            *object,
-                        GCancellable       *cancellable)
+get_stream_thread_func (GTask         *task,
+                        gpointer       source_object,
+                        gpointer       task_data,
+                        GCancellable  *cancellable)
 {
-  GetStreamData *data;
-  GError *error;
-
-  data = g_simple_async_result_get_op_res_gpointer (res);
+  GetStreamData *data = task_data;
+  GIOStream *stream;
+  GError *error = NULL;
 
-  error = NULL;
-  data->stream = g_dbus_address_get_stream_sync (data->address,
-                                                 &data->guid,
-                                                 cancellable,
-                                                 &error);
-  if (data->stream == NULL)
-    g_simple_async_result_take_error (res, error);
+  stream = g_dbus_address_get_stream_sync (data->address,
+                                           &data->guid,
+                                           cancellable,
+                                           &error);
+  if (stream)
+    g_task_return_pointer (task, stream, g_object_unref);
+  else
+    g_task_return_error (task, error);
 }
 
 /**
@@ -853,26 +851,18 @@ g_dbus_address_get_stream (const gchar         *address,
                            GAsyncReadyCallback  callback,
                            gpointer             user_data)
 {
-  GSimpleAsyncResult *res;
+  GTask *task;
   GetStreamData *data;
 
   g_return_if_fail (address != NULL);
 
-  res = g_simple_async_result_new (NULL,
-                                   callback,
-                                   user_data,
-                                   g_dbus_address_get_stream);
-  g_simple_async_result_set_check_cancellable (res, cancellable);
   data = g_new0 (GetStreamData, 1);
   data->address = g_strdup (address);
-  g_simple_async_result_set_op_res_gpointer (res,
-                                             data,
-                                             (GDestroyNotify) get_stream_data_free);
-  g_simple_async_result_run_in_thread (res,
-                                       get_stream_thread_func,
-                                       G_PRIORITY_DEFAULT,
-                                       cancellable);
-  g_object_unref (res);
+
+  task = g_task_new (NULL, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify) get_stream_data_free);
+  g_task_run_in_thread (task, get_stream_thread_func);
+  g_object_unref (task);
 }
 
 /**
@@ -892,26 +882,23 @@ g_dbus_address_get_stream_finish (GAsyncResult        *res,
                                   gchar              **out_guid,
                                   GError             **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+  GTask *task;
   GetStreamData *data;
   GIOStream *ret;
 
-  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
+  g_return_val_if_fail (g_task_is_valid (res, NULL), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_dbus_address_get_stream);
+  task = G_TASK (res);
+  ret = g_task_propagate_pointer (task, error);
 
-  ret = NULL;
-
-  data = g_simple_async_result_get_op_res_gpointer (simple);
-  if (g_simple_async_result_propagate_error (simple, error))
-    goto out;
-
-  ret = g_object_ref (data->stream);
-  if (out_guid != NULL)
-    *out_guid = g_strdup (data->guid);
+  if (ret != NULL && out_guid != NULL)
+    {
+      data = g_task_get_task_data (task);
+      *out_guid = data->guid;
+      data->guid = NULL;
+    }
 
- out:
   return ret;
 }
 
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index cd53c96..50f7920 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -119,7 +119,7 @@
 #include "gasyncinitable.h"
 #include "giostream.h"
 #include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 
 #ifdef G_OS_UNIX
 #include "gunixconnection.h"
@@ -432,7 +432,7 @@ struct _GDBusConnection
   GDBusConnectionFlags flags;
 
   /* Map used for managing method replies, protected by @lock */
-  GHashTable *map_method_serial_to_send_message_data;  /* guint32 -> SendMessageData* */
+  GHashTable *map_method_serial_to_task;  /* guint32 -> GTask* */
 
   /* Maps used for managing signal subscription, protected by @lock */
   GHashTable *map_rule_to_signal_data;                      /* match rule (gchar*)    -> SignalData */
@@ -679,7 +679,7 @@ g_dbus_connection_finalize (GObject *object)
   if (connection->initialization_error != NULL)
     g_error_free (connection->initialization_error);
 
-  g_hash_table_unref (connection->map_method_serial_to_send_message_data);
+  g_hash_table_unref (connection->map_method_serial_to_task);
 
   g_hash_table_unref (connection->map_rule_to_signal_data);
   g_hash_table_unref (connection->map_id_to_signal_data);
@@ -1077,7 +1077,7 @@ g_dbus_connection_init (GDBusConnection *connection)
   g_mutex_init (&connection->lock);
   g_mutex_init (&connection->init_lock);
 
-  connection->map_method_serial_to_send_message_data = g_hash_table_new (g_direct_hash, g_direct_equal);
+  connection->map_method_serial_to_task = g_hash_table_new (g_direct_hash, g_direct_equal);
 
   connection->map_rule_to_signal_data = g_hash_table_new (g_str_hash,
                                                           g_str_equal);
@@ -1210,17 +1210,19 @@ g_dbus_connection_get_capabilities (GDBusConnection *connection)
 
 /* Called in a temporary thread without holding locks. */
 static void
-flush_in_thread_func (GSimpleAsyncResult *res,
-                      GObject            *object,
-                      GCancellable       *cancellable)
+flush_in_thread_func (GTask         *task,
+                      gpointer       source_object,
+                      gpointer       task_data,
+                      GCancellable  *cancellable)
 {
-  GError *error;
+  GError *error = NULL;
 
-  error = NULL;
-  if (!g_dbus_connection_flush_sync (G_DBUS_CONNECTION (object),
-                                     cancellable,
-                                     &error))
-    g_simple_async_result_take_error (res, error);
+  if (g_dbus_connection_flush_sync (source_object,
+                                    cancellable,
+                                    &error))
+    g_task_return_boolean (task, TRUE);
+  else
+    g_task_return_error (task, error);
 }
 
 /**
@@ -1254,20 +1256,13 @@ g_dbus_connection_flush (GDBusConnection     *connection,
                          GAsyncReadyCallback  callback,
                          gpointer             user_data)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
 
   g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
 
-  simple = g_simple_async_result_new (G_OBJECT (connection),
-                                      callback,
-                                      user_data,
-                                      g_dbus_connection_flush);
-  g_simple_async_result_set_check_cancellable (simple, cancellable);
-  g_simple_async_result_run_in_thread (simple,
-                                       flush_in_thread_func,
-                                       G_PRIORITY_DEFAULT,
-                                       cancellable);
-  g_object_unref (simple);
+  task = g_task_new (connection, cancellable, callback, user_data);
+  g_task_run_in_thread (task, flush_in_thread_func);
+  g_object_unref (task);
 }
 
 /**
@@ -1288,24 +1283,11 @@ g_dbus_connection_flush_finish (GDBusConnection  *connection,
                                 GAsyncResult     *res,
                                 GError          **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  gboolean ret;
-
-  ret = FALSE;
-
   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
-  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
+  g_return_val_if_fail (g_task_is_valid (res, connection), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_dbus_connection_flush);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    goto out;
-
-  ret = TRUE;
-
- out:
-  return ret;
+  return g_task_propagate_boolean (G_TASK (res), error);
 }
 
 /**
@@ -1464,7 +1446,7 @@ g_dbus_connection_close (GDBusConnection     *connection,
                          GAsyncReadyCallback  callback,
                          gpointer             user_data)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
 
   g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
 
@@ -1474,13 +1456,9 @@ g_dbus_connection_close (GDBusConnection     *connection,
 
   g_assert (connection->worker != NULL);
 
-  simple = g_simple_async_result_new (G_OBJECT (connection),
-                                      callback,
-                                      user_data,
-                                      g_dbus_connection_close);
-  g_simple_async_result_set_check_cancellable (simple, cancellable);
-  _g_dbus_worker_close (connection->worker, cancellable, simple);
-  g_object_unref (simple);
+  task = g_task_new (connection, cancellable, callback, user_data);
+  _g_dbus_worker_close (connection->worker, task);
+  g_object_unref (task);
 }
 
 /**
@@ -1501,24 +1479,11 @@ g_dbus_connection_close_finish (GDBusConnection  *connection,
                                 GAsyncResult     *res,
                                 GError          **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  gboolean ret;
-
-  ret = FALSE;
-
   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
-  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
+  g_return_val_if_fail (g_task_is_valid (res, connection), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_dbus_connection_close);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    goto out;
-
-  ret = TRUE;
-
- out:
-  return ret;
+  return g_task_propagate_boolean (G_TASK (res), error);
 }
 
 typedef struct {
@@ -1781,14 +1746,7 @@ g_dbus_connection_send_message (GDBusConnection        *connection,
 
 typedef struct
 {
-  volatile gint ref_count;
-  GDBusConnection *connection;
   guint32 serial;
-  GSimpleAsyncResult *simple;
-
-  GMainContext *main_context;
-
-  GCancellable *cancellable;
 
   gulong cancellable_handler_id;
 
@@ -1798,46 +1756,30 @@ typedef struct
 } SendMessageData;
 
 /* Can be called from any thread with or without lock held */
-static SendMessageData *
-send_message_data_ref (SendMessageData *data)
-{
-  g_atomic_int_inc (&data->ref_count);
-  return data;
-}
-
-/* Can be called from any thread with or without lock held */
 static void
-send_message_data_unref (SendMessageData *data)
+send_message_data_free (SendMessageData *data)
 {
-  if (g_atomic_int_dec_and_test (&data->ref_count))
-    {
-      g_assert (data->timeout_source == NULL);
-      g_assert (data->simple == NULL);
-      g_assert (data->cancellable_handler_id == 0);
-      g_object_unref (data->connection);
-      if (data->cancellable != NULL)
-        g_object_unref (data->cancellable);
-      g_main_context_unref (data->main_context);
-      g_free (data);
-    }
+  g_assert (data->timeout_source == NULL);
+  g_assert (data->cancellable_handler_id == 0);
+
+  g_slice_free (SendMessageData, data);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-/* can be called from any thread with lock held - caller must have prepared GSimpleAsyncResult already */
+/* can be called from any thread with lock held */
 static void
-send_message_with_reply_deliver (SendMessageData *data, gboolean remove)
+send_message_with_reply_cleanup (GTask *task, gboolean remove)
 {
-  CONNECTION_ENSURE_LOCK (data->connection);
+  GDBusConnection *connection = g_task_get_source_object (task);
+  SendMessageData *data = g_task_get_task_data (task);
+
+  CONNECTION_ENSURE_LOCK (connection);
 
   g_assert (!data->delivered);
 
   data->delivered = TRUE;
 
-  g_simple_async_result_complete_in_idle (data->simple);
-  g_object_unref (data->simple);
-  data->simple = NULL;
-
   if (data->timeout_source != NULL)
     {
       g_source_destroy (data->timeout_source);
@@ -1845,34 +1787,35 @@ send_message_with_reply_deliver (SendMessageData *data, gboolean remove)
     }
   if (data->cancellable_handler_id > 0)
     {
-      g_cancellable_disconnect (data->cancellable, data->cancellable_handler_id);
+      g_cancellable_disconnect (g_task_get_cancellable (task), data->cancellable_handler_id);
       data->cancellable_handler_id = 0;
     }
 
   if (remove)
     {
-      g_warn_if_fail (g_hash_table_remove (data->connection->map_method_serial_to_send_message_data,
-                                           GUINT_TO_POINTER (data->serial)));
+      gboolean removed = g_hash_table_remove (connection->map_method_serial_to_task,
+                                              GUINT_TO_POINTER (data->serial));
+      g_warn_if_fail (removed);
     }
 
-  send_message_data_unref (data);
+  g_object_unref (task);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 /* Can be called from any thread with lock held */
 static void
-send_message_data_deliver_reply_unlocked (SendMessageData *data,
+send_message_data_deliver_reply_unlocked (GTask           *task,
                                           GDBusMessage    *reply)
 {
+  SendMessageData *data = g_task_get_task_data (task);
+
   if (data->delivered)
     goto out;
 
-  g_simple_async_result_set_op_res_gpointer (data->simple,
-                                             g_object_ref (reply),
-                                             g_object_unref);
+  g_task_return_pointer (task, g_object_ref (reply), g_object_unref);
 
-  send_message_with_reply_deliver (data, TRUE);
+  send_message_with_reply_cleanup (task, TRUE);
 
  out:
   ;
@@ -1884,21 +1827,23 @@ send_message_data_deliver_reply_unlocked (SendMessageData *data,
 static gboolean
 send_message_with_reply_cancelled_idle_cb (gpointer user_data)
 {
-  SendMessageData *data = user_data;
+  GTask *task = user_data;
+  GDBusConnection *connection = g_task_get_source_object (task);
+  SendMessageData *data = g_task_get_task_data (task);
 
-  CONNECTION_LOCK (data->connection);
+  CONNECTION_LOCK (connection);
   if (data->delivered)
     goto out;
 
-  g_simple_async_result_set_error (data->simple,
-                                   G_IO_ERROR,
-                                   G_IO_ERROR_CANCELLED,
-                                   _("Operation was cancelled"));
+  g_task_return_new_error (task,
+                           G_IO_ERROR,
+                           G_IO_ERROR_CANCELLED,
+                           _("Operation was cancelled"));
 
-  send_message_with_reply_deliver (data, TRUE);
+  send_message_with_reply_cleanup (task, TRUE);
 
  out:
-  CONNECTION_UNLOCK (data->connection);
+  CONNECTION_UNLOCK (connection);
   return FALSE;
 }
 
@@ -1907,20 +1852,15 @@ static void
 send_message_with_reply_cancelled_cb (GCancellable *cancellable,
                                       gpointer      user_data)
 {
-  SendMessageData *data = user_data;
+  GTask *task = user_data;
   GSource *idle_source;
 
   /* postpone cancellation to idle handler since we may be called directly
    * via g_cancellable_connect() (e.g. holding lock)
    */
   idle_source = g_idle_source_new ();
-  g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
-  g_source_set_callback (idle_source,
-                         send_message_with_reply_cancelled_idle_cb,
-                         send_message_data_ref (data),
-                         (GDestroyNotify) send_message_data_unref);
   g_source_set_name (idle_source, "[gio] send_message_with_reply_cancelled_idle_cb");
-  g_source_attach (idle_source, data->main_context);
+  g_task_attach_source (task, idle_source, send_message_with_reply_cancelled_idle_cb);
   g_source_unref (idle_source);
 }
 
@@ -1930,21 +1870,23 @@ send_message_with_reply_cancelled_cb (GCancellable *cancellable,
 static gboolean
 send_message_with_reply_timeout_cb (gpointer user_data)
 {
-  SendMessageData *data = user_data;
+  GTask *task = user_data;
+  GDBusConnection *connection = g_task_get_source_object (task);
+  SendMessageData *data = g_task_get_task_data (task);
 
-  CONNECTION_LOCK (data->connection);
+  CONNECTION_LOCK (connection);
   if (data->delivered)
     goto out;
 
-  g_simple_async_result_set_error (data->simple,
-                                   G_IO_ERROR,
-                                   G_IO_ERROR_TIMED_OUT,
-                                   _("Timeout was reached"));
+  g_task_return_new_error (task,
+                           G_IO_ERROR,
+                           G_IO_ERROR_TIMED_OUT,
+                           _("Timeout was reached"));
 
-  send_message_with_reply_deliver (data, TRUE);
+  send_message_with_reply_cleanup (task, TRUE);
 
  out:
-  CONNECTION_UNLOCK (data->connection);
+  CONNECTION_UNLOCK (connection);
 
   return FALSE;
 }
@@ -1962,79 +1904,54 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection     *connect
                                                     GAsyncReadyCallback  callback,
                                                     gpointer             user_data)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
   SendMessageData *data;
-  GError *error;
+  GError *error = NULL;
   volatile guint32 serial;
 
-  data = NULL;
-
   if (out_serial == NULL)
     out_serial = &serial;
 
   if (timeout_msec == -1)
     timeout_msec = 25 * 1000;
 
-  simple = g_simple_async_result_new (G_OBJECT (connection),
-                                      callback,
-                                      user_data,
-                                      g_dbus_connection_send_message_with_reply);
-  g_simple_async_result_set_check_cancellable (simple, cancellable);
+  data = g_slice_new0 (SendMessageData);
+  task = g_task_new (connection, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify) send_message_data_free);
 
-  if (g_cancellable_is_cancelled (cancellable))
+  if (g_task_return_error_if_cancelled (task))
     {
-      g_simple_async_result_set_error (simple,
-                                       G_IO_ERROR,
-                                       G_IO_ERROR_CANCELLED,
-                                       _("Operation was cancelled"));
-      g_simple_async_result_complete_in_idle (simple);
-      g_object_unref (simple);
-      goto out;
+      g_object_unref (task);
+      return;
     }
 
-  error = NULL;
   if (!g_dbus_connection_send_message_unlocked (connection, message, flags, out_serial, &error))
     {
-      g_simple_async_result_take_error (simple, error);
-      g_simple_async_result_complete_in_idle (simple);
-      g_object_unref (simple);
-      goto out;
+      g_task_return_error (task, error);
+      g_object_unref (task);
+      return;
     }
-
-  data = g_new0 (SendMessageData, 1);
-  data->ref_count = 1;
-  data->connection = g_object_ref (connection);
-  data->simple = simple;
   data->serial = *out_serial;
-  data->main_context = g_main_context_ref_thread_default ();
 
   if (cancellable != NULL)
     {
-      data->cancellable = g_object_ref (cancellable);
       data->cancellable_handler_id = g_cancellable_connect (cancellable,
                                                             G_CALLBACK 
(send_message_with_reply_cancelled_cb),
-                                                            send_message_data_ref (data),
-                                                            (GDestroyNotify) send_message_data_unref);
+                                                            g_object_ref (task),
+                                                            g_object_unref);
     }
 
   if (timeout_msec != G_MAXINT)
     {
       data->timeout_source = g_timeout_source_new (timeout_msec);
-      g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT);
-      g_source_set_callback (data->timeout_source,
-                             send_message_with_reply_timeout_cb,
-                             send_message_data_ref (data),
-                             (GDestroyNotify) send_message_data_unref);
-      g_source_attach (data->timeout_source, data->main_context);
+      g_task_attach_source (task, data->timeout_source,
+                            (GSourceFunc) send_message_with_reply_timeout_cb);
       g_source_unref (data->timeout_source);
     }
 
-  g_hash_table_insert (connection->map_method_serial_to_send_message_data,
+  g_hash_table_insert (connection->map_method_serial_to_task,
                        GUINT_TO_POINTER (*out_serial),
-                       data);
-
- out:
-  ;
+                       task);
 }
 
 /**
@@ -2135,23 +2052,11 @@ g_dbus_connection_send_message_with_reply_finish (GDBusConnection  *connection,
                                                   GAsyncResult     *res,
                                                   GError          **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  GDBusMessage *reply;
-
   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
+  g_return_val_if_fail (g_task_is_valid (res, connection), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  reply = NULL;
-
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == 
g_dbus_connection_send_message_with_reply);
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    goto out;
-
-  reply = g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
-
- out:
-  return reply;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -2229,7 +2134,7 @@ g_dbus_connection_send_message_with_reply_sync (GDBusConnection        *connecti
                                                 GCancellable           *cancellable,
                                                 GError                **error)
 {
-  SendMessageSyncData *data;
+  SendMessageSyncData data;
   GDBusMessage *reply;
 
   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
@@ -2238,11 +2143,11 @@ g_dbus_connection_send_message_with_reply_sync (GDBusConnection        *connecti
   g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  data = g_new0 (SendMessageSyncData, 1);
-  data->context = g_main_context_new ();
-  data->loop = g_main_loop_new (data->context, FALSE);
+  data.res = NULL;
+  data.context = g_main_context_new ();
+  data.loop = g_main_loop_new (data.context, FALSE);
 
-  g_main_context_push_thread_default (data->context);
+  g_main_context_push_thread_default (data.context);
 
   g_dbus_connection_send_message_with_reply (connection,
                                              message,
@@ -2251,18 +2156,18 @@ g_dbus_connection_send_message_with_reply_sync (GDBusConnection        *connecti
                                              out_serial,
                                              cancellable,
                                              (GAsyncReadyCallback) send_message_with_reply_sync_cb,
-                                             data);
-  g_main_loop_run (data->loop);
+                                             &data);
+  g_main_loop_run (data.loop);
   reply = g_dbus_connection_send_message_with_reply_finish (connection,
-                                                            data->res,
+                                                            data.res,
                                                             error);
 
-  g_main_context_pop_thread_default (data->context);
+  g_main_context_pop_thread_default (data.context);
 
-  g_main_context_unref (data->context);
-  g_main_loop_unref (data->loop);
-  g_object_unref (data->res);
-  g_free (data);
+  g_main_context_unref (data.context);
+  g_main_loop_unref (data.loop);
+  if (data.res)
+    g_object_unref (data.res);
 
   return reply;
 }
@@ -2348,16 +2253,16 @@ on_worker_message_received (GDBusWorker  *worker,
       if (message_type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN || message_type == G_DBUS_MESSAGE_TYPE_ERROR)
         {
           guint32 reply_serial;
-          SendMessageData *send_message_data;
+          GTask *task;
 
           reply_serial = g_dbus_message_get_reply_serial (message);
           CONNECTION_LOCK (connection);
-          send_message_data = g_hash_table_lookup (connection->map_method_serial_to_send_message_data,
-                                                   GUINT_TO_POINTER (reply_serial));
-          if (send_message_data != NULL)
+          task = g_hash_table_lookup (connection->map_method_serial_to_task,
+                                      GUINT_TO_POINTER (reply_serial));
+          if (task != NULL)
             {
               //g_debug ("delivering reply/error for serial %d for %p", reply_serial, connection);
-              send_message_data_deliver_reply_unlocked (send_message_data, message);
+              send_message_data_deliver_reply_unlocked (task, message);
             }
           else
             {
@@ -2444,21 +2349,22 @@ on_worker_message_about_to_be_sent (GDBusWorker  *worker,
 static gboolean
 cancel_method_on_close (gpointer key, gpointer value, gpointer user_data)
 {
-  SendMessageData *data = value;
+  GTask *task = value;
+  SendMessageData *data = g_task_get_task_data (task);
 
   if (data->delivered)
     return FALSE;
 
-  g_simple_async_result_set_error (data->simple,
-                                   G_IO_ERROR,
-                                   G_IO_ERROR_CLOSED,
-                                   _("The connection is closed"));
+  g_task_return_new_error (task,
+                           G_IO_ERROR,
+                           G_IO_ERROR_CLOSED,
+                           _("The connection is closed"));
 
-  /* Ask send_message_with_reply_deliver not to remove the element from the
+  /* Ask send_message_with_reply_cleanup not to remove the element from the
    * hash table - we're in the middle of a foreach; that would be unsafe.
    * Instead, return TRUE from this function so that it gets removed safely.
    */
-  send_message_with_reply_deliver (data, FALSE);
+  send_message_with_reply_cleanup (task, FALSE);
   return TRUE;
 }
 
@@ -2495,7 +2401,7 @@ on_worker_closed (GDBusWorker *worker,
 
   if (!(old_atomic_flags & FLAG_CLOSED))
     {
-      g_hash_table_foreach_remove (connection->map_method_serial_to_send_message_data, 
cancel_method_on_close, NULL);
+      g_hash_table_foreach_remove (connection->map_method_serial_to_task, cancel_method_on_close, NULL);
       schedule_closed_unlocked (connection, remote_peer_vanished, error);
     }
   CONNECTION_UNLOCK (connection);
@@ -5432,12 +5338,10 @@ decode_method_reply (GDBusMessage        *reply,
 
 typedef struct
 {
-  GSimpleAsyncResult *simple;
   GVariantType *reply_type;
   gchar *method_name; /* for error message */
   guint32 serial;
 
-  GVariant *value;
   GUnixFDList *fd_list;
 } CallState;
 
@@ -5447,8 +5351,6 @@ call_state_free (CallState *state)
   g_variant_type_free (state->reply_type);
   g_free (state->method_name);
 
-  if (state->value != NULL)
-    g_variant_unref (state->value);
   if (state->fd_list != NULL)
     g_object_unref (state->fd_list);
   g_slice_free (CallState, state);
@@ -5460,13 +5362,13 @@ g_dbus_connection_call_done (GObject      *source,
                              GAsyncResult *result,
                              gpointer      user_data)
 {
-  GSimpleAsyncResult *simple;
   GDBusConnection *connection = G_DBUS_CONNECTION (source);
-  CallState *state = user_data;
-  GError *error;
+  GTask *task = user_data;
+  CallState *state = g_task_get_task_data (task);
+  GError *error = NULL;
   GDBusMessage *reply;
+  GVariant *value = NULL;
 
-  error = NULL;
   reply = g_dbus_connection_send_message_with_reply_finish (connection,
                                                             result,
                                                             &error);
@@ -5493,22 +5395,15 @@ g_dbus_connection_call_done (GObject      *source,
     }
 
   if (reply != NULL)
-    state->value = decode_method_reply (reply, state->method_name, state->reply_type, &state->fd_list, 
&error);
+    value = decode_method_reply (reply, state->method_name, state->reply_type, &state->fd_list, &error);
 
-  simple = state->simple; /* why? because state is freed before we unref simple.. */
   if (error != NULL)
-    {
-      g_simple_async_result_take_error (state->simple, error);
-      g_simple_async_result_complete (state->simple);
-      call_state_free (state);
-    }
+    g_task_return_error (task, error);
   else
-    {
-      g_simple_async_result_set_op_res_gpointer (state->simple, state, (GDestroyNotify) call_state_free);
-      g_simple_async_result_complete (state->simple);
-    }
+    g_task_return_pointer (task, value, (GDestroyNotify) g_variant_unref);
+
   g_clear_object (&reply);
-  g_object_unref (simple);
+  g_object_unref (task);
 }
 
 /* called in any thread, with the connection's lock not held */
@@ -5565,12 +5460,9 @@ g_dbus_connection_call_internal (GDBusConnection        *connection,
   if (callback != NULL)
     {
       CallState *state;
+      GTask *task;
 
       state = g_slice_new0 (CallState);
-      state->simple = g_simple_async_result_new (G_OBJECT (connection),
-                                                 callback, user_data,
-                                                 g_dbus_connection_call_internal);
-      g_simple_async_result_set_check_cancellable (state->simple, cancellable);
       state->method_name = g_strjoin (".", interface_name, method_name, NULL);
 
       if (reply_type == NULL)
@@ -5578,6 +5470,9 @@ g_dbus_connection_call_internal (GDBusConnection        *connection,
 
       state->reply_type = g_variant_type_copy (reply_type);
 
+      task = g_task_new (connection, cancellable, callback, user_data);
+      g_task_set_task_data (task, state, (GDestroyNotify) call_state_free);
+
       g_dbus_connection_send_message_with_reply (connection,
                                                  message,
                                                  G_DBUS_SEND_MESSAGE_FLAGS_NONE,
@@ -5585,7 +5480,7 @@ g_dbus_connection_call_internal (GDBusConnection        *connection,
                                                  &state->serial,
                                                  cancellable,
                                                  g_dbus_connection_call_done,
-                                                 state);
+                                                 task);
       serial = state->serial;
     }
   else
@@ -5629,23 +5524,24 @@ g_dbus_connection_call_finish_internal (GDBusConnection  *connection,
                                         GAsyncResult     *res,
                                         GError          **error)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
   CallState *state;
+  GVariant *ret;
 
   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
-  g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (connection),
-                                                        g_dbus_connection_call_internal), NULL);
+  g_return_val_if_fail (g_task_is_valid (res, connection), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  simple = G_SIMPLE_ASYNC_RESULT (res);
+  task = G_TASK (res);
+  state = g_task_get_task_data (task);
 
-  if (g_simple_async_result_propagate_error (simple, error))
+  ret = g_task_propagate_pointer (task, error);
+  if (!ret)
     return NULL;
 
-  state = g_simple_async_result_get_op_res_gpointer (simple);
   if (out_fd_list != NULL)
     *out_fd_list = state->fd_list != NULL ? g_object_ref (state->fd_list) : NULL;
-  return g_variant_ref (state->value);
+  return ret;
 }
 
 /* called in any user thread, with the connection's lock not held */
@@ -7069,26 +6965,22 @@ bus_get_async_initable_cb (GObject      *source_object,
                            GAsyncResult *res,
                            gpointer      user_data)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-  GError *error;
+  GTask *task = user_data;
+  GError *error = NULL;
 
-  error = NULL;
   if (!g_async_initable_init_finish (G_ASYNC_INITABLE (source_object),
                                      res,
                                      &error))
     {
       g_assert (error != NULL);
-      g_simple_async_result_take_error (simple, error);
+      g_task_return_error (task, error);
       g_object_unref (source_object);
     }
   else
     {
-      g_simple_async_result_set_op_res_gpointer (simple,
-                                                 source_object,
-                                                 g_object_unref);
+      g_task_return_pointer (task, source_object, g_object_unref);
     }
-  g_simple_async_result_complete_in_idle (simple);
-  g_object_unref (simple);
+  g_object_unref (task);
 }
 
 /**
@@ -7115,23 +7007,17 @@ g_bus_get (GBusType             bus_type,
            gpointer             user_data)
 {
   GDBusConnection *connection;
-  GSimpleAsyncResult *simple;
-  GError *error;
+  GTask *task;
+  GError *error = NULL;
 
-  simple = g_simple_async_result_new (NULL,
-                                      callback,
-                                      user_data,
-                                      g_bus_get);
-  g_simple_async_result_set_check_cancellable (simple, cancellable);
+  task = g_task_new (NULL, cancellable, callback, user_data);
 
-  error = NULL;
   connection = get_uninitialized_connection (bus_type, cancellable, &error);
   if (connection == NULL)
     {
       g_assert (error != NULL);
-      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);
     }
   else
     {
@@ -7139,7 +7025,7 @@ g_bus_get (GBusType             bus_type,
                                    G_PRIORITY_DEFAULT,
                                    cancellable,
                                    bus_get_async_initable_cb,
-                                   simple);
+                                   task);
     }
 }
 
@@ -7169,25 +7055,10 @@ GDBusConnection *
 g_bus_get_finish (GAsyncResult  *res,
                   GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-  GObject *object;
-  GDBusConnection *ret;
-
+  g_return_val_if_fail (g_task_is_valid (res, NULL), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_bus_get);
-
-  ret = NULL;
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    goto out;
-
-  object = g_simple_async_result_get_op_res_gpointer (simple);
-  g_assert (object != NULL);
-  ret = g_object_ref (G_DBUS_CONNECTION (object));
-
- out:
-  return ret;
+  return g_task_propagate_pointer (G_TASK (res), error);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c
index 60af6c6..a52bec2 100644
--- a/gio/gdbusprivate.c
+++ b/gio/gdbusprivate.c
@@ -29,8 +29,7 @@
 #include "gdbusmessage.h"
 #include "gdbuserror.h"
 #include "gdbusintrospection.h"
-#include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "ginputstream.h"
 #include "gmemoryinputstream.h"
 #include "giostream.h"
@@ -99,28 +98,17 @@ _g_dbus_hexdump (const gchar *data, gsize len, guint indent)
 
 typedef struct
 {
-  GSocket *socket;
-  GCancellable *cancellable;
-
   void *buffer;
   gsize count;
 
   GSocketControlMessage ***messages;
   gint *num_messages;
-
-  GSimpleAsyncResult *simple;
-
-  gboolean from_mainloop;
 } ReadWithControlData;
 
 static void
 read_with_control_data_free (ReadWithControlData *data)
 {
-  g_object_unref (data->socket);
-  if (data->cancellable != NULL)
-    g_object_unref (data->cancellable);
-  g_object_unref (data->simple);
-  g_free (data);
+  g_slice_free (ReadWithControlData, data);
 }
 
 static gboolean
@@ -128,7 +116,8 @@ _g_socket_read_with_control_messages_ready (GSocket      *socket,
                                             GIOCondition  condition,
                                             gpointer      user_data)
 {
-  ReadWithControlData *data = user_data;
+  GTask *task = user_data;
+  ReadWithControlData *data = g_task_get_task_data (task);
   GError *error;
   gssize result;
   GInputVector vector;
@@ -136,29 +125,28 @@ _g_socket_read_with_control_messages_ready (GSocket      *socket,
   error = NULL;
   vector.buffer = data->buffer;
   vector.size = data->count;
-  result = g_socket_receive_message (data->socket,
+  result = g_socket_receive_message (socket,
                                      NULL, /* address */
                                      &vector,
                                      1,
                                      data->messages,
                                      data->num_messages,
                                      NULL,
-                                     data->cancellable,
+                                     g_task_get_cancellable (task),
                                      &error);
-  if (result >= 0)
-    {
-      g_simple_async_result_set_op_res_gssize (data->simple, result);
-    }
-  else
+
+  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
     {
-      g_assert (error != NULL);
-      g_simple_async_result_take_error (data->simple, error);
+      g_error_free (error);
+      return TRUE;
     }
 
-  if (data->from_mainloop)
-    g_simple_async_result_complete (data->simple);
+  g_assert (result >= 0 || error != NULL);
+  if (result >= 0)
+    g_task_return_int (task, result);
   else
-    g_simple_async_result_complete_in_idle (data->simple);
+    g_task_return_error (task, error);
+  g_object_unref (task);
 
   return FALSE;
 }
@@ -174,41 +162,30 @@ _g_socket_read_with_control_messages (GSocket                 *socket,
                                       GAsyncReadyCallback      callback,
                                       gpointer                 user_data)
 {
+  GTask *task;
   ReadWithControlData *data;
+  GSource *source;
 
-  data = g_new0 (ReadWithControlData, 1);
-  data->socket = g_object_ref (socket);
-  data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
+  data = g_slice_new0 (ReadWithControlData);
   data->buffer = buffer;
   data->count = count;
   data->messages = messages;
   data->num_messages = num_messages;
 
-  data->simple = g_simple_async_result_new (G_OBJECT (socket),
-                                            callback,
-                                            user_data,
-                                            _g_socket_read_with_control_messages);
-  g_simple_async_result_set_check_cancellable (data->simple, cancellable);
+  task = g_task_new (socket, cancellable, callback, user_data);
+  g_task_set_task_data (task, data, (GDestroyNotify) read_with_control_data_free);
 
-  if (!g_socket_condition_check (socket, G_IO_IN))
+  if (g_socket_condition_check (socket, G_IO_IN))
     {
-      GSource *source;
-      data->from_mainloop = TRUE;
-      source = g_socket_create_source (data->socket,
-                                       G_IO_IN | G_IO_HUP | G_IO_ERR,
-                                       cancellable);
-      g_source_set_callback (source,
-                             (GSourceFunc) _g_socket_read_with_control_messages_ready,
-                             data,
-                             (GDestroyNotify) read_with_control_data_free);
-      g_source_attach (source, g_main_context_get_thread_default ());
-      g_source_unref (source);
-    }
-  else
-    {
-      _g_socket_read_with_control_messages_ready (data->socket, G_IO_IN, data);
-      read_with_control_data_free (data);
+      if (!_g_socket_read_with_control_messages_ready (socket, G_IO_IN, task))
+        return;
     }
+
+  source = g_socket_create_source (socket,
+                                   G_IO_IN | G_IO_HUP | G_IO_ERR,
+                                   cancellable);
+  g_task_attach_source (task, source, (GSourceFunc) _g_socket_read_with_control_messages_ready);
+  g_source_unref (source);
 }
 
 static gssize
@@ -216,15 +193,10 @@ _g_socket_read_with_control_messages_finish (GSocket       *socket,
                                              GAsyncResult  *result,
                                              GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
   g_return_val_if_fail (G_IS_SOCKET (socket), -1);
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == _g_socket_read_with_control_messages);
+  g_return_val_if_fail (g_task_is_valid (result, socket), -1);
 
-  if (g_simple_async_result_propagate_error (simple, error))
-      return -1;
-  else
-    return g_simple_async_result_get_op_res_gssize (simple);
+  return g_task_propagate_int (G_TASK (result), error);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -252,7 +224,7 @@ ensure_required_types (void)
 {
   g_assert (ensured_classes == NULL);
   ensured_classes = g_ptr_array_new ();
-  ensure_type (G_TYPE_SIMPLE_ASYNC_RESULT);
+  ensure_type (G_TYPE_TASK);
   ensure_type (G_TYPE_MEMORY_INPUT_STREAM);
 }
 /* ---------------------------------------------------------------------------------------------------- */
@@ -422,17 +394,12 @@ static void write_message_print_transport_debug (gssize bytes_written,
 
 typedef struct {
     GDBusWorker *worker;
-    GCancellable *cancellable;
-    GSimpleAsyncResult *result;
+    GTask *task;
 } CloseData;
 
 static void close_data_free (CloseData *close_data)
 {
-  if (close_data->cancellable != NULL)
-    g_object_unref (close_data->cancellable);
-
-  if (close_data->result != NULL)
-    g_object_unref (close_data->result);
+  g_clear_object (&close_data->task);
 
   _g_dbus_worker_unref (close_data->worker);
   g_slice_free (CloseData, close_data);
@@ -890,9 +857,8 @@ struct _MessageToWriteData
   gchar        *blob;
   gsize         blob_size;
 
-  gsize               total_written;
-  GSimpleAsyncResult *simple;
-
+  gsize         total_written;
+  GTask        *task;
 };
 
 static void
@@ -902,7 +868,7 @@ message_to_write_data_free (MessageToWriteData *data)
   if (data->message)
     g_object_unref (data->message);
   g_free (data->blob);
-  g_free (data);
+  g_slice_free (MessageToWriteData, data);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -920,14 +886,14 @@ write_message_async_cb (GObject      *source_object,
                         gpointer      user_data)
 {
   MessageToWriteData *data = user_data;
-  GSimpleAsyncResult *simple;
+  GTask *task;
   gssize bytes_written;
   GError *error;
 
-  /* Note: we can't access data->simple after calling g_async_result_complete () because the
+  /* Note: we can't access data->task after calling g_task_return_* () because the
    * callback can free @data and we're not completing in idle. So use a copy of the pointer.
    */
-  simple = data->simple;
+  task = data->task;
 
   error = NULL;
   bytes_written = g_output_stream_write_finish (G_OUTPUT_STREAM (source_object),
@@ -935,9 +901,8 @@ write_message_async_cb (GObject      *source_object,
                                                 &error);
   if (bytes_written == -1)
     {
-      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);
       goto out;
     }
   g_assert (bytes_written > 0); /* zero is never returned */
@@ -948,8 +913,8 @@ write_message_async_cb (GObject      *source_object,
   g_assert (data->total_written <= data->blob_size);
   if (data->total_written == data->blob_size)
     {
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
+      g_task_return_boolean (task, TRUE);
+      g_object_unref (task);
       goto out;
     }
 
@@ -986,15 +951,15 @@ write_message_continue_writing (MessageToWriteData *data)
 {
   GOutputStream *ostream;
 #ifdef G_OS_UNIX
-  GSimpleAsyncResult *simple;
+  GTask *task;
   GUnixFDList *fd_list;
 #endif
 
 #ifdef G_OS_UNIX
-  /* Note: we can't access data->simple after calling g_async_result_complete () because the
+  /* Note: we can't access data->task after calling g_task_return_* () because the
    * callback can free @data and we're not completing in idle. So use a copy of the pointer.
    */
-  simple = data->simple;
+  task = data->task;
 #endif
 
   ostream = g_io_stream_get_output_stream (data->worker->stream);
@@ -1024,12 +989,11 @@ write_message_continue_writing (MessageToWriteData *data)
         {
           if (!(data->worker->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING))
             {
-              g_simple_async_result_set_error (simple,
-                                               G_IO_ERROR,
-                                               G_IO_ERROR_FAILED,
-                                               "Tried sending a file descriptor but remote peer does not 
support this capability");
-              g_simple_async_result_complete (simple);
-              g_object_unref (simple);
+              g_task_return_new_error (task,
+                                       G_IO_ERROR,
+                                       G_IO_ERROR_FAILED,
+                                       "Tried sending a file descriptor but remote peer does not support 
this capability");
+              g_object_unref (task);
               goto out;
             }
           control_message = g_unix_fd_message_new_with_fd_list (fd_list);
@@ -1066,9 +1030,8 @@ write_message_continue_writing (MessageToWriteData *data)
               g_error_free (error);
               goto out;
             }
-          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);
           goto out;
         }
       g_assert (bytes_written > 0); /* zero is never returned */
@@ -1079,8 +1042,8 @@ write_message_continue_writing (MessageToWriteData *data)
       g_assert (data->total_written <= data->blob_size);
       if (data->total_written == data->blob_size)
         {
-          g_simple_async_result_complete (simple);
-          g_object_unref (simple);
+          g_task_return_boolean (task, TRUE);
+          g_object_unref (task);
           goto out;
         }
 
@@ -1092,13 +1055,12 @@ write_message_continue_writing (MessageToWriteData *data)
 #ifdef G_OS_UNIX
       if (fd_list != NULL)
         {
-          g_simple_async_result_set_error (simple,
-                                           G_IO_ERROR,
-                                           G_IO_ERROR_FAILED,
-                                           "Tried sending a file descriptor on unsupported stream of type 
%s",
-                                           g_type_name (G_TYPE_FROM_INSTANCE (ostream)));
-          g_simple_async_result_complete (simple);
-          g_object_unref (simple);
+          g_task_return_new_error (task,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_FAILED,
+                                   "Tried sending a file descriptor on unsupported stream of type %s",
+                                   g_type_name (G_TYPE_FROM_INSTANCE (ostream)));
+          g_object_unref (task);
           goto out;
         }
 #endif
@@ -1128,10 +1090,7 @@ write_message_async (GDBusWorker         *worker,
                      GAsyncReadyCallback  callback,
                      gpointer             user_data)
 {
-  data->simple = g_simple_async_result_new (NULL,
-                                            callback,
-                                            user_data,
-                                            write_message_async);
+  data->task = g_task_new (NULL, NULL, callback, user_data);
   data->total_written = 0;
   write_message_continue_writing (data);
 }
@@ -1141,11 +1100,9 @@ static gboolean
 write_message_finish (GAsyncResult   *res,
                       GError        **error)
 {
-  g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == write_message_async);
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
-    return FALSE;
-  else
-    return TRUE;
+  g_return_val_if_fail (g_task_is_valid (res, NULL), FALSE);
+
+  return g_task_propagate_boolean (G_TASK (res), error);
 }
 /* ---------------------------------------------------------------------------------------------------- */
 
@@ -1398,15 +1355,12 @@ iostream_close_cb (GObject      *source_object,
       pending_close_attempts = g_list_delete_link (pending_close_attempts,
                                                    pending_close_attempts);
 
-      if (close_data->result != NULL)
+      if (close_data->task != NULL)
         {
           if (error != NULL)
-            g_simple_async_result_set_from_error (close_data->result, error);
-
-          /* this must be in an idle because the result is likely to be
-           * intended for another thread
-           */
-          g_simple_async_result_complete_in_idle (close_data->result);
+            g_task_return_error (close_data->task, g_error_copy (error));
+          else
+            g_task_return_boolean (close_data->task, TRUE);
         }
 
       close_data_free (close_data);
@@ -1640,7 +1594,7 @@ _g_dbus_worker_send_message (GDBusWorker    *worker,
   g_return_if_fail (blob != NULL);
   g_return_if_fail (blob_len > 16);
 
-  data = g_new0 (MessageToWriteData, 1);
+  data = g_slice_new0 (MessageToWriteData);
   data->worker = _g_dbus_worker_ref (worker);
   data->message = g_object_ref (message);
   data->blob = blob; /* steal! */
@@ -1717,16 +1671,13 @@ _g_dbus_worker_new (GIOStream                              *stream,
  */
 void
 _g_dbus_worker_close (GDBusWorker         *worker,
-                      GCancellable        *cancellable,
-                      GSimpleAsyncResult  *result)
+                      GTask               *task)
 {
   CloseData *close_data;
 
   close_data = g_slice_new0 (CloseData);
   close_data->worker = _g_dbus_worker_ref (worker);
-  close_data->cancellable =
-      (cancellable == NULL ? NULL : g_object_ref (cancellable));
-  close_data->result = (result == NULL ? NULL : g_object_ref (result));
+  close_data->task = (task == NULL ? NULL : g_object_ref (task));
 
   /* Don't set worker->close_expected here - we're in the wrong thread.
    * It'll be set before the actual close happens.
@@ -1752,7 +1703,7 @@ _g_dbus_worker_stop (GDBusWorker *worker)
   /* Cancel any pending operations and schedule a close of the underlying I/O
    * stream in the worker thread
    */
-  _g_dbus_worker_close (worker, NULL, NULL);
+  _g_dbus_worker_close (worker, NULL);
 
   /* _g_dbus_worker_close holds a ref until after an idle in the worker
    * thread has run, so we no longer need to unref in an idle like in
diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h
index 0e38121..b1f4890 100644
--- a/gio/gdbusprivate.h
+++ b/gio/gdbusprivate.h
@@ -76,8 +76,7 @@ gboolean     _g_dbus_worker_flush_sync   (GDBusWorker    *worker,
 
 /* can be called from any thread */
 void         _g_dbus_worker_close        (GDBusWorker         *worker,
-                                          GCancellable        *cancellable,
-                                          GSimpleAsyncResult  *result);
+                                          GTask               *task);
 
 /* ---------------------------------------------------------------------------------------------------- */
 
diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c
index 33492b7..ecba626 100644
--- a/gio/gdbusproxy.c
+++ b/gio/gdbusproxy.c
@@ -32,8 +32,7 @@
 #include "ginitable.h"
 #include "gasyncinitable.h"
 #include "gioerror.h"
-#include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
 #include "gcancellable.h"
 #include "gdbusinterface.h"
 
@@ -1411,29 +1410,12 @@ on_name_owner_changed (GDBusConnection *connection,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-typedef struct
-{
-  GDBusProxy *proxy;
-  GCancellable *cancellable;
-  GSimpleAsyncResult *simple;
-} AsyncInitData;
-
-static void
-async_init_data_free (AsyncInitData *data)
-{
-  g_object_unref (data->proxy);
-  if (data->cancellable != NULL)
-    g_object_unref (data->cancellable);
-  g_object_unref (data->simple);
-  g_free (data);
-}
-
 static void
 async_init_get_all_cb (GDBusConnection *connection,
                        GAsyncResult    *res,
                        gpointer         user_data)
 {
-  AsyncInitData *data = user_data;
+  GTask *task = user_data;
   GVariant *result;
   GError *error;
 
@@ -1456,40 +1438,35 @@ async_init_get_all_cb (GDBusConnection *connection,
       //g_debug ("error: %d %d %s", error->domain, error->code, error->message);
       g_error_free (error);
     }
-  else
-    {
-      g_simple_async_result_set_op_res_gpointer (data->simple,
-                                                 result,
-                                                 (GDestroyNotify) g_variant_unref);
-    }
 
-  g_simple_async_result_complete_in_idle (data->simple);
-  async_init_data_free (data);
+  g_task_return_pointer (task, result,
+                         (GDestroyNotify) g_variant_unref);
+  g_object_unref (task);
 }
 
 static void
-async_init_data_set_name_owner (AsyncInitData *data,
-                                const gchar   *name_owner)
+async_init_data_set_name_owner (GTask       *task,
+                                const gchar *name_owner)
 {
+  GDBusProxy *proxy = g_task_get_source_object (task);
   gboolean get_all;
 
-
   if (name_owner != NULL)
     {
       /* it starts as NULL anyway */
       G_LOCK (properties_lock);
-      data->proxy->priv->name_owner = g_strdup (name_owner);
+      proxy->priv->name_owner = g_strdup (name_owner);
       G_UNLOCK (properties_lock);
     }
 
   get_all = TRUE;
 
-  if (data->proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES)
+  if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES)
     {
       /* Don't load properties if the API user doesn't want them */
       get_all = FALSE;
     }
-  else if (name_owner == NULL && data->proxy->priv->name != NULL)
+  else if (name_owner == NULL && proxy->priv->name != NULL)
     {
       /* Don't attempt to load properties if the name_owner is NULL (which
        * usually means the name isn't owned), unless name is also NULL (which
@@ -1502,23 +1479,23 @@ async_init_data_set_name_owner (AsyncInitData *data,
   if (get_all)
     {
       /* load all properties asynchronously */
-      g_dbus_connection_call (data->proxy->priv->connection,
+      g_dbus_connection_call (proxy->priv->connection,
                               name_owner,
-                              data->proxy->priv->object_path,
+                              proxy->priv->object_path,
                               "org.freedesktop.DBus.Properties",
                               "GetAll",
-                              g_variant_new ("(s)", data->proxy->priv->interface_name),
+                              g_variant_new ("(s)", proxy->priv->interface_name),
                               G_VARIANT_TYPE ("(a{sv})"),
                               G_DBUS_CALL_FLAGS_NONE,
                               -1,           /* timeout */
-                              data->cancellable,
+                              g_task_get_cancellable (task),
                               (GAsyncReadyCallback) async_init_get_all_cb,
-                              data);
+                              task);
     }
   else
     {
-      g_simple_async_result_complete_in_idle (data->simple);
-      async_init_data_free (data);
+      g_task_return_pointer (task, NULL, NULL);
+      g_object_unref (task);
     }
 }
 
@@ -1527,7 +1504,7 @@ async_init_get_name_owner_cb (GDBusConnection *connection,
                               GAsyncResult    *res,
                               gpointer         user_data)
 {
-  AsyncInitData *data = user_data;
+  GTask *task = user_data;
   GError *error;
   GVariant *result;
 
@@ -1541,13 +1518,12 @@ async_init_get_name_owner_cb (GDBusConnection *connection,
           error->code == G_DBUS_ERROR_NAME_HAS_NO_OWNER)
         {
           g_error_free (error);
-          async_init_data_set_name_owner (data, NULL);
+          async_init_data_set_name_owner (task, NULL);
         }
       else
         {
-          g_simple_async_result_take_error (data->simple, error);
-          g_simple_async_result_complete_in_idle (data->simple);
-          async_init_data_free (data);
+          g_task_return_error (task, error);
+          g_object_unref (task);
         }
     }
   else
@@ -1556,27 +1532,29 @@ async_init_get_name_owner_cb (GDBusConnection *connection,
       const gchar *name_owner;
 
       g_variant_get (result, "(&s)", &name_owner);
-      async_init_data_set_name_owner (data, name_owner);
+      async_init_data_set_name_owner (task, name_owner);
       g_variant_unref (result);
     }
 }
 
 static void
-async_init_call_get_name_owner (AsyncInitData *data)
+async_init_call_get_name_owner (GTask *task)
 {
-  g_dbus_connection_call (data->proxy->priv->connection,
+  GDBusProxy *proxy = g_task_get_source_object (task);
+
+  g_dbus_connection_call (proxy->priv->connection,
                           "org.freedesktop.DBus",  /* name */
                           "/org/freedesktop/DBus", /* object path */
                           "org.freedesktop.DBus",  /* interface */
                           "GetNameOwner",
                           g_variant_new ("(s)",
-                                         data->proxy->priv->name),
+                                         proxy->priv->name),
                           G_VARIANT_TYPE ("(s)"),
                           G_DBUS_CALL_FLAGS_NONE,
                           -1,           /* timeout */
-                          data->cancellable,
+                          g_task_get_cancellable (task),
                           (GAsyncReadyCallback) async_init_get_name_owner_cb,
-                          data);
+                          task);
 }
 
 static void
@@ -1584,7 +1562,8 @@ async_init_start_service_by_name_cb (GDBusConnection *connection,
                                      GAsyncResult    *res,
                                      gpointer         user_data)
 {
-  AsyncInitData *data = user_data;
+  GTask *task = user_data;
+  GDBusProxy *proxy = g_task_get_source_object (task);
   GError *error;
   GVariant *result;
 
@@ -1628,7 +1607,7 @@ async_init_start_service_by_name_cb (GDBusConnection *connection,
             {
               g_prefix_error (&error,
                               _("Error calling StartServiceByName for %s: "),
-                              data->proxy->priv->name);
+                              proxy->priv->name);
               g_free (remote_error);
               goto failed;
             }
@@ -1652,38 +1631,39 @@ async_init_start_service_by_name_cb (GDBusConnection *connection,
                                G_IO_ERROR_FAILED,
                                _("Unexpected reply %d from StartServiceByName(\"%s\") method"),
                                start_service_result,
-                               data->proxy->priv->name);
+                               proxy->priv->name);
           goto failed;
         }
     }
 
-  async_init_call_get_name_owner (data);
+  async_init_call_get_name_owner (task);
   return;
 
  failed:
   g_warn_if_fail (error != NULL);
-  g_simple_async_result_take_error (data->simple, error);
-  g_simple_async_result_complete_in_idle (data->simple);
-  async_init_data_free (data);
+  g_task_return_error (task, error);
+  g_object_unref (task);
 }
 
 static void
-async_init_call_start_service_by_name (AsyncInitData *data)
+async_init_call_start_service_by_name (GTask *task)
 {
-  g_dbus_connection_call (data->proxy->priv->connection,
+  GDBusProxy *proxy = g_task_get_source_object (task);
+
+  g_dbus_connection_call (proxy->priv->connection,
                           "org.freedesktop.DBus",  /* name */
                           "/org/freedesktop/DBus", /* object path */
                           "org.freedesktop.DBus",  /* interface */
                           "StartServiceByName",
                           g_variant_new ("(su)",
-                                         data->proxy->priv->name,
+                                         proxy->priv->name,
                                          0),
                           G_VARIANT_TYPE ("(u)"),
                           G_DBUS_CALL_FLAGS_NONE,
                           -1,           /* timeout */
-                          data->cancellable,
+                          g_task_get_cancellable (task),
                           (GAsyncReadyCallback) async_init_start_service_by_name_cb,
-                          data);
+                          task);
 }
 
 static void
@@ -1694,37 +1674,31 @@ async_initable_init_second_async (GAsyncInitable      *initable,
                                   gpointer             user_data)
 {
   GDBusProxy *proxy = G_DBUS_PROXY (initable);
-  AsyncInitData *data;
+  GTask *task;
 
-  data = g_new0 (AsyncInitData, 1);
-  data->proxy = g_object_ref (proxy);
-  data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
-  data->simple = g_simple_async_result_new (G_OBJECT (proxy),
-                                            callback,
-                                            user_data,
-                                            NULL);
-  g_simple_async_result_set_check_cancellable (data->simple, cancellable);
+  task = g_task_new (proxy, cancellable, callback, user_data);
+  g_task_set_priority (task, io_priority);
 
   /* Check name ownership asynchronously - possibly also start the service */
   if (proxy->priv->name == NULL)
     {
       /* Do nothing */
-      async_init_data_set_name_owner (data, NULL);
+      async_init_data_set_name_owner (task, NULL);
     }
   else if (g_dbus_is_unique_name (proxy->priv->name))
     {
-      async_init_data_set_name_owner (data, proxy->priv->name);
+      async_init_data_set_name_owner (task, proxy->priv->name);
     }
   else
     {
       if ((proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) ||
           (proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION))
         {
-          async_init_call_get_name_owner (data);
+          async_init_call_get_name_owner (task);
         }
       else
         {
-          async_init_call_start_service_by_name (data);
+          async_init_call_start_service_by_name (task);
         }
     }
 }
@@ -1735,24 +1709,18 @@ async_initable_init_second_finish (GAsyncInitable  *initable,
                                    GError         **error)
 {
   GDBusProxy *proxy = G_DBUS_PROXY (initable);
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+  GTask *task = G_TASK (res);
   GVariant *result;
   gboolean ret;
 
-  ret = FALSE;
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    goto out;
+  ret = !g_task_had_error (task);
 
-  result = g_simple_async_result_get_op_res_gpointer (simple);
+  result = g_task_propagate_pointer (task, error);
   if (result != NULL)
     {
       process_get_all_reply (proxy, result);
     }
 
-  ret = TRUE;
-
- out:
   proxy->priv->initialized = TRUE;
   return ret;
 }
@@ -1815,7 +1783,7 @@ async_initable_init_first (GAsyncInitable *initable)
 /* ---------------------------------------------------------------------------------------------------- */
 
 /* initialization is split into two parts - the first is the
- * non-blocing part that requires the callers GMainContext - the
+ * non-blocking part that requires the callers GMainContext - the
  * second is a blocking part async part that doesn't require the
  * callers GMainContext.. we do this split so the code can be reused
  * in the GInitable implementation below.
@@ -1824,52 +1792,46 @@ async_initable_init_first (GAsyncInitable *initable)
  * paths.
  */
 
-typedef struct
+static void
+init_second_async_cb (GObject       *source_object,
+                     GAsyncResult  *res,
+                     gpointer       user_data)
 {
-  GDBusProxy          *proxy;
-  gint                 io_priority;
-  GCancellable        *cancellable;
-  GAsyncReadyCallback  callback;
-  gpointer             user_data;
-} GetConnectionData;
+  GTask *task = user_data;
+  GError *error = NULL;
+
+  if (async_initable_init_second_finish (G_ASYNC_INITABLE (source_object), res, &error))
+    g_task_return_boolean (task, TRUE);
+  else
+    g_task_return_error (task, error);
+  g_object_unref (task);
+}
 
 static void
 get_connection_cb (GObject       *source_object,
                    GAsyncResult  *res,
                    gpointer       user_data)
 {
-  GetConnectionData *data = user_data;
+  GTask *task = user_data;
+  GDBusProxy *proxy = g_task_get_source_object (task);
   GError *error;
 
   error = NULL;
-  data->proxy->priv->connection = g_bus_get_finish (res, &error);
-  if (data->proxy->priv->connection == NULL)
-    {
-      GSimpleAsyncResult *simple;
-      simple = g_simple_async_result_new (G_OBJECT (data->proxy),
-                                          data->callback,
-                                          data->user_data,
-                                          NULL);
-      g_simple_async_result_set_check_cancellable (simple, data->cancellable);
-      g_simple_async_result_take_error (simple, error);
-      g_simple_async_result_complete_in_idle (simple);
-      g_object_unref (simple);
+  proxy->priv->connection = g_bus_get_finish (res, &error);
+  if (proxy->priv->connection == NULL)
+    {
+      g_task_return_error (task, error);
+      g_object_unref (task);
     }
   else
     {
-      async_initable_init_first (G_ASYNC_INITABLE (data->proxy));
-      async_initable_init_second_async (G_ASYNC_INITABLE (data->proxy),
-                                        data->io_priority,
-                                        data->cancellable,
-                                        data->callback,
-                                        data->user_data);
+      async_initable_init_first (G_ASYNC_INITABLE (proxy));
+      async_initable_init_second_async (G_ASYNC_INITABLE (proxy),
+                                        g_task_get_priority (task),
+                                        g_task_get_cancellable (task),
+                                        init_second_async_cb,
+                                        task);
     }
-
-  if (data->cancellable != NULL)
-    g_object_unref (data->cancellable);
-
-  g_object_unref (data->proxy);
-  g_free (data);
 }
 
 static void
@@ -1880,28 +1842,25 @@ async_initable_init_async (GAsyncInitable      *initable,
                            gpointer             user_data)
 {
   GDBusProxy *proxy = G_DBUS_PROXY (initable);
+  GTask *task;
+
+  task = g_task_new (proxy, cancellable, callback, user_data);
+  g_task_set_priority (task, io_priority);
 
   if (proxy->priv->bus_type != G_BUS_TYPE_NONE)
     {
-      GetConnectionData *data;
-
       g_assert (proxy->priv->connection == NULL);
 
-      data = g_new0 (GetConnectionData, 1);
-      data->proxy = g_object_ref (proxy);
-      data->io_priority = io_priority;
-      data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
-      data->callback = callback;
-      data->user_data = user_data;
       g_bus_get (proxy->priv->bus_type,
                  cancellable,
                  get_connection_cb,
-                 data);
+                 task);
     }
   else
     {
       async_initable_init_first (initable);
-      async_initable_init_second_async (initable, io_priority, cancellable, callback, user_data);
+      async_initable_init_second_async (initable, io_priority, cancellable,
+                                        init_second_async_cb, task);
     }
 }
 
@@ -1910,7 +1869,7 @@ async_initable_init_finish (GAsyncInitable  *initable,
                             GAsyncResult    *res,
                             GError         **error)
 {
-  return async_initable_init_second_finish (initable, res, error);
+  return g_task_propagate_boolean (G_TASK (res), error);
 }
 
 static void
@@ -2586,7 +2545,7 @@ reply_cb (GDBusConnection *connection,
           GAsyncResult    *res,
           gpointer         user_data)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+  GTask *task = user_data;
   GVariant *value;
   GError *error;
 #ifdef G_OS_UNIX
@@ -2606,7 +2565,7 @@ reply_cb (GDBusConnection *connection,
 #endif
   if (error != NULL)
     {
-      g_simple_async_result_take_error (simple, error);
+      g_task_return_error (task, error);
     }
   else
     {
@@ -2616,12 +2575,10 @@ reply_cb (GDBusConnection *connection,
 #ifdef G_OS_UNIX
       data->fd_list = fd_list;
 #endif
-      g_simple_async_result_set_op_res_gpointer (simple, data, (GDestroyNotify) reply_data_free);
+      g_task_return_pointer (task, data, (GDestroyNotify) reply_data_free);
     }
 
-  /* no need to complete in idle since the method GDBusConnection already does */
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
+  g_object_unref (task);
 }
 
 /* properties_lock must be held for as long as you will keep the
@@ -2683,7 +2640,7 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
 {
-  GSimpleAsyncResult *simple;
+  GTask *task;
   gboolean was_split;
   gchar *split_interface_name;
   const gchar *split_method_name;
@@ -2713,16 +2670,12 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
   if (callback != NULL)
     {
       my_callback = (GAsyncReadyCallback) reply_cb;
-      simple = g_simple_async_result_new (G_OBJECT (proxy),
-                                          callback,
-                                          user_data,
-                                          g_dbus_proxy_call_internal);
-      g_simple_async_result_set_check_cancellable (simple, cancellable);
+      task = g_task_new (proxy, cancellable, callback, user_data);
     }
   else
     {
       my_callback = NULL;
-      simple = NULL;
+      task = NULL;
     }
 
   G_LOCK (properties_lock);
@@ -2746,14 +2699,13 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
       destination = g_strdup (get_destination_for_call (proxy));
       if (destination == NULL)
         {
-          if (simple != NULL)
+          if (task != NULL)
             {
-              g_simple_async_result_set_error (simple,
-                                               G_IO_ERROR,
-                                               G_IO_ERROR_FAILED,
-                                               _("Cannot invoke method; proxy is for a well-known name 
without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
-              g_simple_async_result_complete_in_idle (simple);
-              g_object_unref (simple);
+              g_task_return_new_error (task,
+                                       G_IO_ERROR,
+                                       G_IO_ERROR_FAILED,
+                                       _("Cannot invoke method; proxy is for a well-known name without an 
owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
+              g_object_unref (task);
             }
           G_UNLOCK (properties_lock);
           goto out;
@@ -2775,7 +2727,7 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
                                             fd_list,
                                             cancellable,
                                             my_callback,
-                                            simple);
+                                            task);
 #else
   g_dbus_connection_call (proxy->priv->connection,
                           destination,
@@ -2788,7 +2740,7 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
                           timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
                           cancellable,
                           my_callback,
-                          simple);
+                          task);
 #endif
 
  out:
@@ -2805,27 +2757,25 @@ g_dbus_proxy_call_finish_internal (GDBusProxy    *proxy,
                                    GAsyncResult  *res,
                                    GError       **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
   GVariant *value;
   ReplyData *data;
 
   g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
-  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
+  g_return_val_if_fail (g_task_is_valid (res, proxy), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_dbus_proxy_call_internal);
-
   value = NULL;
 
-  if (g_simple_async_result_propagate_error (simple, error))
+  data = g_task_propagate_pointer (G_TASK (res), error);
+  if (!data)
     goto out;
 
-  data = g_simple_async_result_get_op_res_gpointer (simple);
   value = g_variant_ref (data->value);
 #ifdef G_OS_UNIX
   if (out_fd_list != NULL)
     *out_fd_list = data->fd_list != NULL ? g_object_ref (data->fd_list) : NULL;
 #endif
+  reply_data_free (data);
 
  out:
   return value;


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