[at-spi2-core] Add time-out, and support inspecting our own app



commit f422c2ec7bea75dcb0e1e1f7c30806b9e35a70a1
Author: Mike Gorse <mgorse novell com>
Date:   Wed Dec 1 13:58:09 2010 -0500

    Add time-out, and support inspecting our own app

 atspi/atspi-misc-private.h |    2 +
 atspi/atspi-misc.c         |  106 ++++++++++++++++++++++++++++++++++++++++----
 dbind/dbind.c              |   36 +++------------
 3 files changed, 105 insertions(+), 39 deletions(-)
---
diff --git a/atspi/atspi-misc-private.h b/atspi/atspi-misc-private.h
index 9953c29..304f6a6 100644
--- a/atspi/atspi-misc-private.h
+++ b/atspi/atspi-misc-private.h
@@ -140,6 +140,8 @@ GArray *_atspi_dbus_attribute_array_from_message (DBusMessage *message);
 
 GArray *_atspi_dbus_attribute_array_from_iter (DBusMessageIter *iter);
 
+gboolean _atspi_process_deferred_messages (gpointer data);
+
 #define _ATSPI_DBUS_CHECK_SIG(message, type, ret) \
   if (!message) { \
     g_warning ("at-spi: Got no message at %s line %d\n", __FILE__, __LINE__); \
diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c
index a8f0ac9..9485be0 100644
--- a/atspi/atspi-misc.c
+++ b/atspi/atspi-misc.c
@@ -610,6 +610,91 @@ handle_add_accessible (DBusConnection *bus, DBusMessage *message, void *user_dat
   add_accessible_from_iter (&iter);
 }
 
+typedef struct
+{
+  DBusConnection *bus;
+  DBusMessage *message;
+  void *data;
+} BusDataClosure;
+
+static guint process_deferred_messages_id = -1;
+
+static void
+process_deferred_message (BusDataClosure *closure)
+{
+  int type = dbus_message_get_type (closure->message);
+  const char *interface = dbus_message_get_interface (closure->message);
+  const char *member = dbus_message_get_member (closure->message); 
+  dbus_uint32_t v;
+  char *bus_name;
+
+  if (type == DBUS_MESSAGE_TYPE_SIGNAL &&
+      !strncmp (interface, "org.a11y.atspi.Event.", 21))
+  {
+    atspi_dbus_handle_event (closure->bus, closure->message, closure->data);
+  }
+  if (dbus_message_is_method_call (closure->message, atspi_interface_device_event_listener, "NotifyEvent"))
+  {
+    atspi_dbus_handle_DeviceEvent (closure->bus,
+                                   closure->message, closure->data);
+  }
+  if (dbus_message_is_signal (closure->message, atspi_interface_cache, "AddAccessible"))
+  {
+    handle_add_accessible (closure->bus, closure->message, closure->data);
+  }
+  if (dbus_message_is_signal (closure->message, atspi_interface_cache, "RemoveAccessible"))
+  {
+    handle_remove_accessible (closure->bus, closure->message, closure->data);
+  }
+}
+
+static GList *deferred_messages = NULL;
+
+gboolean
+_atspi_process_deferred_messages (gpointer data)
+{
+  static int in_process_deferred_messages = 0;
+
+  if (in_process_deferred_messages)
+    return;
+  in_process_deferred_messages = 1;
+  while (deferred_messages != NULL)
+  {
+    BusDataClosure *closure = deferred_messages->data;
+    process_deferred_message (closure);
+    deferred_messages = g_list_remove (deferred_messages, closure);
+    dbus_message_unref (closure->message);
+    dbus_connection_unref (closure->bus);
+    g_free (closure);
+  }
+  /* If data is NULL, assume that we were called from GLib */
+  if (!data)
+    process_deferred_messages_id = -1;
+  in_process_deferred_messages = 0;
+  return FALSE;
+}
+
+static DBusHandlerResult
+defer_message (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+  BusDataClosure *closure = g_new (BusDataClosure, 1);
+  GList *new_list;
+
+  if (!closure)
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+  closure->bus = dbus_connection_ref (bus);
+  closure->message = dbus_message_ref (message);
+  closure->data = user_data;
+
+  new_list = g_list_append (deferred_messages, closure);
+  if (new_list)
+    deferred_messages = new_list;
+
+  if (process_deferred_messages_id == -1)
+    process_deferred_messages_id = g_idle_add (_atspi_process_deferred_messages, NULL);
+  return DBUS_HANDLER_RESULT_HANDLED;
+}
+
 static DBusHandlerResult
 atspi_dbus_filter (DBusConnection *bus, DBusMessage *message, void *data)
 {
@@ -622,21 +707,20 @@ atspi_dbus_filter (DBusConnection *bus, DBusMessage *message, void *data)
   if (type == DBUS_MESSAGE_TYPE_SIGNAL &&
       !strncmp (interface, "org.a11y.atspi.Event.", 21))
   {
-    return atspi_dbus_handle_event (bus, message, data);
+    return defer_message (bus, message, data);
   }
   if (dbus_message_is_method_call (message, atspi_interface_device_event_listener, "NotifyEvent"))
   {
-    return atspi_dbus_handle_DeviceEvent (bus, message, data);
+    return defer_message (bus, message, data);
   }
   if (dbus_message_is_signal (message, atspi_interface_cache, "AddAccessible"))
   {
-    return handle_add_accessible (bus, message, data);
+    return defer_message (bus, message, data);
   }
   if (dbus_message_is_signal (message, atspi_interface_cache, "RemoveAccessible"))
   {
-    return handle_remove_accessible (bus, message, data);
+    return defer_message (bus, message, data);
   }
-  /* TODO: Handle ChildrenChanged, StateChanged, PropertyChanged */
   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
@@ -788,6 +872,7 @@ atspi_init (void)
   dbus_bus_register (bus, &error);
   dbus_connection_setup_with_g_main(bus, g_main_context_default());
   dbus_connection_add_filter (bus, atspi_dbus_filter, NULL, NULL);
+  dbind_set_timeout (1000);
   match = g_strdup_printf ("type='signal',interface='%s',member='AddAccessible'", atspi_interface_cache);
   dbus_error_init (&error);
   dbus_bus_add_match (bus, match, &error);
@@ -883,6 +968,7 @@ _atspi_dbus_call (gpointer obj, const char *interface, const char *method, GErro
   dbus_error_init (&err);
   retval = dbind_method_call_reentrant_va (_atspi_bus(), aobj->app->bus_name, aobj->path, interface, method, &err, type, args);
   va_end (args);
+  _atspi_process_deferred_messages ((gpointer)TRUE);
   if (dbus_error_is_set (&err))
   {
     /* TODO: Set gerror */
@@ -932,6 +1018,7 @@ _atspi_dbus_call_partial_va (gpointer obj,
     reply = dbind_send_and_allow_reentry (_atspi_bus(), msg, &err);
 out:
   va_end (args);
+  _atspi_process_deferred_messages ((gpointer)TRUE);
   if (dbus_error_is_set (&err))
   {
     /* TODO: Set gerror */
@@ -950,7 +1037,7 @@ _atspi_dbus_get_property (gpointer obj, const char *interface, const char *name,
   AtspiObject *aobj = ATSPI_OBJECT (obj);
 
   if (!aobj)
-    return NULL;
+    return FALSE;
 
   message = dbus_message_new_method_call (aobj->app->bus_name,
                                           aobj->path,
@@ -963,8 +1050,9 @@ _atspi_dbus_get_property (gpointer obj, const char *interface, const char *name,
   }
   dbus_message_append_args (message, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
   dbus_error_init (&err);
-  reply = dbus_connection_send_with_reply_and_block (_atspi_bus(), message, 1000, &err);
+  reply = dbind_send_and_allow_reentry (_atspi_bus(), message, &err);
   dbus_message_unref (message);
+  _atspi_process_deferred_messages ((gpointer)TRUE);
   if (!reply)
   {
     // TODO: throw exception
@@ -1000,8 +1088,8 @@ _atspi_dbus_send_with_reply_and_block (DBusMessage *message)
   DBusError err;
 
   dbus_error_init (&err);
-  /* TODO: Write this function; allow reentrancy */
-  reply = dbus_connection_send_with_reply_and_block (_atspi_bus(), message, 1000, &err);
+  reply = dbind_send_and_allow_reentry (_atspi_bus(), message, &err);
+  _atspi_process_deferred_messages ((gpointer)TRUE);
   dbus_message_unref (message);
   if (err.message)
     g_warning ("Atspi: Got error: %s\n", err.message);
diff --git a/dbind/dbind.c b/dbind/dbind.c
index 294f6c1..b090e06 100644
--- a/dbind/dbind.c
+++ b/dbind/dbind.c
@@ -18,9 +18,7 @@ static int dbind_timeout = -1;
 
 typedef struct _SpiReentrantCallClosure 
 {
-  GMainLoop   *loop;
   DBusMessage *reply;
-  guint timeout;
 } SpiReentrantCallClosure;
 
 static void
@@ -29,15 +27,6 @@ set_reply (DBusPendingCall * pending, void *user_data)
   SpiReentrantCallClosure* closure = (SpiReentrantCallClosure *) user_data; 
 
   closure->reply = dbus_pending_call_steal_reply (pending);
-  g_main_loop_quit (closure->loop);
-}
-
-gboolean
-main_loop_timeout (SpiReentrantCallClosure *closure)
-{
-  g_main_loop_quit (closure->loop);
-  /* Returning TRUE because caller will remove the timer */
-  return TRUE;
 }
 
 DBusMessage *
@@ -50,32 +39,19 @@ dbind_send_and_allow_reentry (DBusConnection * bus, DBusMessage * message, DBusE
               dbus_bus_get_unique_name (bus)) != 0)
     return dbus_connection_send_with_reply_and_block (bus, message, dbind_timeout, error);
 
-  /* TODO: Figure out why this isn't working */
-  return NULL;
+  closure.reply = NULL;
+  dbus_connection_setup_with_g_main(bus, NULL);
   if (!dbus_connection_send_with_reply (bus, message, &pending, dbind_timeout))
       return NULL;
   dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL);
-  closure.loop = g_main_loop_new (NULL, FALSE);
-  closure.reply = NULL;
-  dbus_connection_setup_with_g_main(bus, NULL);
 
-  if (1)
-    {
-      closure.timeout = g_timeout_add_seconds (2, main_loop_timeout, &closure);
-      g_main_loop_run  (closure.loop);
-      g_source_remove (closure.timeout);
-    }
-  else
+  closure.reply = NULL;
+  while (!closure.reply)
     {
-      closure.reply = NULL;
-      while (!closure.reply)
-        {
-          if (!dbus_connection_read_write_dispatch (bus, dbind_timeout))
-            return NULL;
-        }
+      if (!dbus_connection_read_write_dispatch (bus, dbind_timeout))
+        return NULL;
     }
   
-  g_main_loop_unref (closure.loop);
   return closure.reply;
 }
 



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