Enhancements to atk-bridge, so that it gracefully recovers from at-spi-registry failure.
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Wed, 19 Jun 2002 21:18:26 +0000 (21:18 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Wed, 19 Jun 2002 21:18:26 +0000 (21:18 +0000)
git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@322 e2bd861d-eb25-0410-b326-f6ed22b6b98c

ChangeLog
atk-bridge/bridge.c

index a956d9e85dd02d83af6d4a736a35ca5635ba90f5..9b88d3700f68dbb3764c20512dd06e746d0318b9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2002-06-19  Bill Haneman  <bill.haneman@sun.com>
 
+       * atk-bridge/bridge.c:  [partial fix for bug 85305]
+       (spi_atk_bridge_register_application):
+       New method where the initial application registry calls have been
+       moved; it allows an application to re-register in response to
+       certain error conditions (such as a registry restart, see below).
+       (atk_bridge_init):
+       Moved some initialization code to the method
+       spi_atk_bridge_get_registry, below.
+       (spi_atk_bridge_get_registry):
+       New, private accessor function for the Accessibility_Registry
+       instance.  If the registry has not been started before, or has
+       died (as detected by failure of a CORBA exception), it is
+       restarted before return, and spi_atk_bridge_register_application
+       is called again to register with the new bridge instance.
+       (spi_atk_emit_eventv):
+       Set registry_died on error; use spi_atk_bridge_get_registry () to
+       access the registry.
+       
        * registryd/registry.c:
        (impl_accessibility_registry_register_global_event_listener):
        Set listener's event_type_quark to etype.minor instead of
index 2d1bb1e4083c1fe6857f4165c00b95855e420aac..21809395994c4d66864b5837165b2e07fae76c47 100644 (file)
 #undef SPI_BRIDGE_DEBUG
 
 static CORBA_Environment ev;
-static Accessibility_Registry registry;
+static Accessibility_Registry registry = NULL;
 static SpiApplication *this_app = NULL;
+static gboolean registry_died = FALSE;
 
+static Accessibility_Registry spi_atk_bridge_get_registry (void);
 static void     spi_atk_bridge_exit_func               (void);
 static void     spi_atk_register_event_listeners       (void);
 static void     spi_atk_bridge_focus_tracker           (AtkObject             *object);
+static void     spi_atk_bridge_register_application    (Accessibility_Registry registry);
 static gboolean spi_atk_bridge_property_event_listener (GSignalInvocationHint *signal_hint,
                                                        guint                  n_param_values,
                                                        const GValue          *param_values,
@@ -107,18 +110,7 @@ atk_bridge_init (gint *argc, gchar **argv[])
 
   CORBA_exception_init(&ev);
 
-  registry = bonobo_activation_activate_from_id (
-         "OAFIID:Accessibility_Registry:1.0", 0, NULL, &ev);
-  
-  if (ev._major != CORBA_NO_EXCEPTION)
-    {
-      g_error ("Accessibility app error: exception during "
-              "registry activation from id: %s\n",
-              CORBA_exception_id (&ev));
-      CORBA_exception_free (&ev);
-    }
-
-  if (registry == CORBA_OBJECT_NIL)
+  if (spi_atk_bridge_get_registry () == CORBA_OBJECT_NIL)
     {
       g_error ("Could not locate registry");
     }
@@ -131,19 +123,51 @@ atk_bridge_init (gint *argc, gchar **argv[])
 
   fprintf (stderr, "About to register application\n");
 
-  Accessibility_Registry_registerApplication (registry,
-                                              BONOBO_OBJREF (this_app),
-                                              &ev);
-
+  spi_atk_bridge_register_application (spi_atk_bridge_get_registry ());
+  
   g_atexit (spi_atk_bridge_exit_func);
 
-  spi_atk_register_event_listeners ();
-
   fprintf (stderr, "Application registered & listening\n");
 
   return 0;
 }
 
+static void
+spi_atk_bridge_register_application (Accessibility_Registry registry)
+{
+  Accessibility_Registry_registerApplication (spi_atk_bridge_get_registry (),
+                                              BONOBO_OBJREF (this_app),
+                                              &ev);
+  spi_atk_register_event_listeners ();
+}
+
+static Accessibility_Registry
+spi_atk_bridge_get_registry ()
+{
+  CORBA_Environment ev;
+
+  if (registry_died || (registry == NULL)) {
+         CORBA_exception_init (&ev);
+         if (registry_died) g_warning ("registry died! restarting...");
+         registry = bonobo_activation_activate_from_id (
+                 "OAFIID:Accessibility_Registry:1.0", 0, NULL, &ev);
+         
+         if (ev._major != CORBA_NO_EXCEPTION)
+         {
+                 g_error ("Accessibility app error: exception during "
+                          "registry activation from id: %s\n",
+                          CORBA_exception_id (&ev));
+                 CORBA_exception_free (&ev);
+         }
+         
+         if (registry_died && registry) {
+                 registry_died = FALSE;
+                 spi_atk_bridge_register_application (registry);
+         }
+  }
+  return registry;
+}
+
 int
 gtk_module_init (gint *argc, gchar **argv[])
 {
@@ -235,8 +259,8 @@ spi_atk_register_event_listeners (void)
 static void
 deregister_application (BonoboObject *app)
 {
-  Accessibility_Registry_deregisterApplication (
-         registry, BONOBO_OBJREF (app), &ev);
+  Accessibility_Registry registry = spi_atk_bridge_get_registry ();    
+  Accessibility_Registry_deregisterApplication (registry, BONOBO_OBJREF (app), &ev);
 
   registry = bonobo_object_release_unref (registry, &ev);
   
@@ -328,7 +352,9 @@ spi_atk_bridge_focus_tracker (AtkObject *object)
   e.detail1 = 0;
   e.detail2 = 0;
 
-  Accessibility_Registry_notifyEvent (registry, &e, &ev);
+  Accessibility_Registry_notifyEvent (spi_atk_bridge_get_registry (), &e, &ev);
+  if (BONOBO_EX (&ev)) registry_died = TRUE;
+  
   Accessibility_Accessible_unref (e.source, &ev);
   
   CORBA_exception_free (&ev);
@@ -382,7 +408,8 @@ spi_atk_emit_eventv (GObject      *gobject,
       CORBA_free (s);
 #endif
 
-      Accessibility_Registry_notifyEvent (registry, &e, &ev);
+      Accessibility_Registry_notifyEvent (spi_atk_bridge_get_registry (), &e, &ev);
+      if (BONOBO_EX (&ev)) registry_died = TRUE;
       Accessibility_Accessible_unref (e.source, &ev);
 
       CORBA_exception_free (&ev);
@@ -523,12 +550,14 @@ spi_atk_bridge_key_listener (AtkKeyEventStruct *event, gpointer data)
        g_warning ("failure: pre-listener get dec\n");
 
   controller =
-    Accessibility_Registry_getDeviceEventController (registry, &ev);
+    Accessibility_Registry_getDeviceEventController (
+           spi_atk_bridge_get_registry (), &ev);
 
   if (BONOBO_EX (&ev))
     {
       g_warning ("failure: no deviceeventcontroller found\n");
       CORBA_exception_free (&ev);
+      registry_died = TRUE;
       result = FALSE;
     }
   else