Fix object lifecycle errors.
authorMark Doffman <mark.doffman@codethink.co.uk>
Tue, 5 Jan 2010 20:50:55 +0000 (12:50 -0800)
committerMark Doffman <mark.doffman@codethink.co.uk>
Tue, 5 Jan 2010 20:50:55 +0000 (12:50 -0800)
Add an application reference to the event structure.

Makefile.am
atk-adaptor/accessible-cache.c
atk-adaptor/accessible-leasing.c
atk-adaptor/accessible-register.c
atk-adaptor/adaptors/accessible-adaptor.c
atk-adaptor/adaptors/cache-adaptor.c
atk-adaptor/bridge.c
atk-adaptor/event.c
configure.ac
droute/droute.c

index 31982fe..ca33cea 100644 (file)
@@ -1 +1 @@
-SUBDIRS=droute common atk-adaptor
+SUBDIRS=dbind droute common atk-adaptor
index 4f87b18..c7e27f9 100644 (file)
@@ -38,7 +38,7 @@ toplevel_added_listener (AtkObject * accessible,
                          guint index, AtkObject * child);
 
 static void
                          guint index, AtkObject * child);
 
 static void
-remove_object (gpointer data, GObject * gobj);
+remove_object (GObject * source, GObject * gobj, gpointer data);
 
 static void
 add_object (SpiCache * cache, GObject * gobj);
 
 static void
 add_object (SpiCache * cache, GObject * gobj);
@@ -149,7 +149,7 @@ spi_cache_dispose (GObject * object)
 /*---------------------------------------------------------------------------*/
 
 static void
 /*---------------------------------------------------------------------------*/
 
 static void
-remove_object (gpointer data, GObject * gobj)
+remove_object (GObject * source, GObject * gobj, gpointer data)
 {
   SpiCache *cache = SPI_CACHE (data);
   
 {
   SpiCache *cache = SPI_CACHE (data);
   
@@ -167,6 +167,12 @@ add_object (SpiCache * cache, GObject * gobj)
 
   g_hash_table_insert (cache->objects, gobj, NULL);
 
 
   g_hash_table_insert (cache->objects, gobj, NULL);
 
+#ifdef SPI_ATK_DEBUG
+  g_debug ("CACHE  - %s - %d - %s", atk_object_get_name (ATK_OBJECT (gobj)),
+            atk_object_get_role (ATK_OBJECT (gobj)),
+            spi_register_object_to_path (spi_global_register, gobj));
+#endif
+
   g_signal_emit (cache, cache_signals [OBJECT_ADDED], 0, gobj);
 }
 
   g_signal_emit (cache, cache_signals [OBJECT_ADDED], 0, gobj);
 }
 
@@ -254,11 +260,6 @@ add_subtree (SpiCache *cache, AtkObject * accessible)
           if (!spi_cache_in (cache, G_OBJECT (current)) &&
               !atk_state_set_contains_state  (set, ATK_STATE_MANAGES_DESCENDANTS))
             {
           if (!spi_cache_in (cache, G_OBJECT (current)) &&
               !atk_state_set_contains_state  (set, ATK_STATE_MANAGES_DESCENDANTS))
             {
-#ifdef SPI_ATK_DEBUG
-              g_debug ("REG  - %s - %d - %s", atk_object_get_name (current),
-                       atk_object_get_role (current),
-                       atk_dbus_object_to_path (current));
-#endif
               append_children (current, traversal);
             }
         }
               append_children (current, traversal);
             }
         }
@@ -386,4 +387,20 @@ spi_cache_in (SpiCache * cache, GObject * object)
     return FALSE;
 }
 
     return FALSE;
 }
 
+#ifdef SPI_ATK_DEBUG
+void
+spi_cache_print_info (GObject * obj)
+{
+  char * path = spi_register_object_to_path (spi_global_register, obj);
+  if (spi_cache_in (spi_global_cache, obj))
+      g_printf ("%s IC\n", path);
+  else
+      g_printf ("%s NC\n", path);
+
+  if (path)
+      g_free (path);
+}
+#endif
+
 /*END------------------------------------------------------------------------*/
 /*END------------------------------------------------------------------------*/
index 28d4099..63f3c3a 100644 (file)
 
 #include "accessible-leasing.h"
 
 
 #include "accessible-leasing.h"
 
+#ifdef SPI_ATK_DEBUG
+#include "accessible-cache.h"
+#endif
+
 /*---------------------------------------------------------------------------*/
 
 SpiLeasing *spi_global_leasing;
 /*---------------------------------------------------------------------------*/
 
 SpiLeasing *spi_global_leasing;
@@ -108,6 +112,11 @@ expiry_func (gpointer data)
     {
       current = g_queue_pop_head (leasing->expiry_queue);
 
     {
       current = g_queue_pop_head (leasing->expiry_queue);
 
+#ifdef SPI_ATK_DEBUG
+      g_debug ("REVOKE - ");
+      spi_cache_print_info (current->object);
+#endif
+
       g_object_unref (current->object);
       g_slice_free (ExpiryElement, current);
 
       g_object_unref (current->object);
       g_slice_free (ExpiryElement, current);
 
@@ -192,6 +201,11 @@ spi_leasing_take (SpiLeasing * leasing, GObject * object)
 
   add_expiry_timeout (leasing);
 
 
   add_expiry_timeout (leasing);
 
+#ifdef SPI_ATK_DEBUG
+  g_debug ("LEASE - ");
+  spi_cache_print_info (object);
+#endif
+
   return object;
 }
 
   return object;
 }
 
index ac93dee..97ada1d 100644 (file)
@@ -198,6 +198,10 @@ deregister_object (gpointer data, GObject * gobj)
                      0,
                      gobj);
       g_hash_table_remove (reg->ref2ptr, GINT_TO_POINTER (ref));
                      0,
                      gobj);
       g_hash_table_remove (reg->ref2ptr, GINT_TO_POINTER (ref));
+
+#ifdef SPI_ATK_DEBUG
+      g_debug ("DEREG  - %d", ref);
+#endif
     }
 }
 
     }
 }
 
@@ -213,6 +217,10 @@ register_object (SpiRegister * reg, GObject * gobj)
   g_object_set_data (G_OBJECT (gobj), SPI_DBUS_ID, GINT_TO_POINTER (ref));
   g_object_weak_ref (G_OBJECT (gobj), deregister_object, reg);
 
   g_object_set_data (G_OBJECT (gobj), SPI_DBUS_ID, GINT_TO_POINTER (ref));
   g_object_weak_ref (G_OBJECT (gobj), deregister_object, reg);
 
+#ifdef SPI_ATK_DEBUG
+  g_debug ("REG  - %d", ref);
+#endif
+
   g_signal_emit (reg, register_signals [OBJECT_REGISTERED], 0, gobj);
 }
 
   g_signal_emit (reg, register_signals [OBJECT_REGISTERED], 0, gobj);
 }
 
@@ -268,6 +276,9 @@ spi_register_object_to_path (SpiRegister * reg, GObject * gobj)
 {
   guint ref;
 
 {
   guint ref;
 
+  if (gobj == NULL)
+    return NULL;
+
   ref = object_to_ref (gobj);
   if (!ref)
     {
   ref = object_to_ref (gobj);
   if (!ref)
     {
index 6359fa7..844ab6a 100644 (file)
@@ -76,11 +76,59 @@ impl_set_Description (DBusMessageIter * iter, void *user_data)
 static dbus_bool_t
 impl_get_Parent (DBusMessageIter * iter, void *user_data)
 {
 static dbus_bool_t
 impl_get_Parent (DBusMessageIter * iter, void *user_data)
 {
-  AtkObject *object = (AtkObject *) user_data;
+  AtkObject *obj = (AtkObject *) user_data;
+  AtkObject *parent;
+  DBusMessageIter iter_variant;
+  dbus_uint32_t role;
 
   g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
 
 
   g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
 
-  spi_object_append_v_reference (iter, atk_object_get_parent (object));
+  role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
+
+  dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)",
+                                    &iter_variant);
+
+  parent = atk_object_get_parent (obj);
+  if (parent == NULL)
+    {
+#ifdef SPI_ATK_PLUG_SOCKET
+      /* TODO, move in to a 'Plug' wrapper. */
+      if (ATK_IS_PLUG (obj))
+        {
+          char *id = g_object_get_data (G_OBJECT (obj), "dbus-plug-parent");
+          char *bus_parent;
+          char *path_parent;
+
+          if (id)
+            {
+              bus_parent = g_strdup (id);
+            if (bus_parent && (path_parent = g_utf8_strchr (bus_parent + 1, -1, ':')))
+              {
+                DBusMessageIter iter_parent;
+                *(path_parent++) = '\0';
+                dbus_message_iter_open_container (&iter_variant, DBUS_TYPE_STRUCT, NULL,
+                                                  &iter_parent);
+                dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_STRING, &bus_parent);
+                dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_OBJECT_PATH, &path_parent);
+                dbus_message_iter_close_container (&iter_variant, &iter_parent);
+              }
+            }
+        }
+      else if (role != Accessibility_ROLE_APPLICATION)
+#else
+      if (role != Accessibility_ROLE_APPLICATION)
+#endif
+         spi_object_append_null_reference (&iter_variant);
+      else
+         spi_object_append_desktop_reference (&iter_variant);
+      }
+  else
+    {
+      spi_object_append_reference (&iter_variant, parent);
+    }
+
+
+  dbus_message_iter_close_container (iter, &iter_variant);
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -413,7 +461,7 @@ static DBusMessage *
 impl_GetApplication (DBusConnection * bus,
                      DBusMessage * message, void *user_data)
 {
 impl_GetApplication (DBusConnection * bus,
                      DBusMessage * message, void *user_data)
 {
-  AtkObject *root = atk_get_root ();
+  AtkObject *root = g_object_ref (atk_get_root ());
   return spi_object_return_reference (message, root);
 }
 
   return spi_object_return_reference (message, root);
 }
 
index 45eb41b..15595a5 100644 (file)
@@ -98,9 +98,30 @@ append_cache_item (AtkObject * obj, gpointer data)
     parent = atk_object_get_parent (obj);
     if (parent == NULL)
       {
     parent = atk_object_get_parent (obj);
     if (parent == NULL)
       {
-        /* TODO: Support getting parent of an AtkPlug */
-#ifdef __ATK_PLUG_H__
-        if (role != Accessibility_ROLE_APPLICATION && !ATK_IS_PLUG (obj))
+#ifdef SPI_ATK_PLUG_SOCKET
+        /* TODO, move in to a 'Plug' wrapper. */
+        if (ATK_IS_PLUG (obj))
+          {
+            char *id = g_object_get_data (G_OBJECT (obj), "dbus-plug-parent");
+            char *bus_parent;
+            char *path_parent;
+
+            if (id)
+              {
+                bus_parent = g_strdup (id);
+              if (bus_parent && (path_parent = g_utf8_strchr (bus_parent + 1, -1, ':')))
+                {
+                  DBusMessageIter iter_parent;
+                  *(path_parent++) = '\0';
+                  dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_STRUCT, NULL,
+                                                    &iter_parent);
+                  dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_STRING, &bus_parent);
+                  dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_OBJECT_PATH, &path_parent);
+                  dbus_message_iter_close_container (&iter_struct, &iter_parent);
+                }
+              }
+          }
+        else if (role != Accessibility_ROLE_APPLICATION)
 #else
         if (role != Accessibility_ROLE_APPLICATION)
 #endif
 #else
         if (role != Accessibility_ROLE_APPLICATION)
 #endif
@@ -131,7 +152,7 @@ append_cache_item (AtkObject * obj, gpointer data)
             g_object_unref (G_OBJECT (child));
           }
       }
             g_object_unref (G_OBJECT (child));
           }
       }
-#ifdef __ATK_PLUG_H__
+#ifdef SPI_ATK_PLUG_SOCKET
     if (ATK_IS_SOCKET (obj) && atk_socket_is_occupied (ATK_SOCKET (obj)))
       {
         AtkSocket *socket = ATK_SOCKET (obj);
     if (ATK_IS_SOCKET (obj) && atk_socket_is_occupied (ATK_SOCKET (obj)))
       {
         AtkSocket *socket = ATK_SOCKET (obj);
@@ -144,8 +165,8 @@ append_cache_item (AtkObject * obj, gpointer data)
             *(child_path++) = '\0';
             dbus_message_iter_open_container (&iter_sub_array, DBUS_TYPE_STRUCT, NULL,
                                               &iter_socket);
             *(child_path++) = '\0';
             dbus_message_iter_open_container (&iter_sub_array, DBUS_TYPE_STRUCT, NULL,
                                               &iter_socket);
-            dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_STRING, &name);
-            dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_OBJECT_PATH, &path);
+            dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_STRING, &child_name);
+            dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_OBJECT_PATH, &child_path);
             dbus_message_iter_close_container (&iter_sub_array, &iter_socket);
           }
         g_free (child_name);
             dbus_message_iter_close_container (&iter_sub_array, &iter_socket);
           }
         g_free (child_name);
index b283506..aaf2bcc 100644 (file)
@@ -246,7 +246,7 @@ exit_func (void)
 
 /*---------------------------------------------------------------------------*/
 
 
 /*---------------------------------------------------------------------------*/
 
-#ifdef __ATK_PLUG_H__
+#ifdef SPI_ATK_PLUG_SOCKET
 static AtkPlugClass *plug_class;
 static AtkSocketClass *socket_class;
 
 static AtkPlugClass *plug_class;
 static AtkSocketClass *socket_class;
 
@@ -257,7 +257,7 @@ get_plug_id (AtkPlug * plug)
   gchar *path;
   GString *str = g_string_new (NULL);
 
   gchar *path;
   GString *str = g_string_new (NULL);
 
-  path = atk_dbus_object_to_path (ATK_OBJECT (plug), TRUE);
+  path = spi_register_object_to_path (spi_global_register, G_OBJECT (plug));
   g_string_printf (str, "%s:%s", uname, path);
   g_free (path);
   return g_string_free (str, FALSE);
   g_string_printf (str, "%s:%s", uname, path);
   g_free (path);
   return g_string_free (str, FALSE);
@@ -270,8 +270,7 @@ socket_embed_hook (AtkSocket * socket, gchar * plug_id)
   gchar *plug_name, *plug_path;
 
   /* Force registration */
   gchar *plug_name, *plug_path;
 
   /* Force registration */
-  gchar *path = atk_dbus_object_to_path (accessible, TRUE);
-  spi_emit_cache_update (accessible, atk_adaptor_app_data->bus);
+  gchar *path = spi_register_object_to_path (spi_global_register, G_OBJECT (accessible));
   /* Let the plug know that it has been embedded */
   plug_name = g_strdup (plug_id);
   if (!plug_name)
   /* Let the plug know that it has been embedded */
   plug_name = g_strdup (plug_id);
   if (!plug_name)
@@ -286,7 +285,7 @@ socket_embed_hook (AtkSocket * socket, gchar * plug_id)
       *(plug_path++) = '\0';
       message = dbus_message_new_method_call (plug_name, plug_path, "org.freedesktop.atspi.Accessible", "Embedded");
       dbus_message_append_args (message, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID);
       *(plug_path++) = '\0';
       message = dbus_message_new_method_call (plug_name, plug_path, "org.freedesktop.atspi.Accessible", "Embedded");
       dbus_message_append_args (message, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID);
-      dbus_connection_send (atk_adaptor_app_data->bus, message, NULL);
+      dbus_connection_send (spi_global_app_data->bus, message, NULL);
     }
   g_free (plug_name);
   g_free (path);
     }
   g_free (plug_name);
   g_free (path);
@@ -358,7 +357,7 @@ adaptor_init (gint * argc, gchar ** argv[])
   /* Allocate global data and do ATK initializations */
   spi_global_app_data = g_new0 (SpiBridge, 1);
   atk_misc = atk_misc_get_instance ();
   /* Allocate global data and do ATK initializations */
   spi_global_app_data = g_new0 (SpiBridge, 1);
   atk_misc = atk_misc_get_instance ();
-  spi_global_app_data->root = root;
+  spi_global_app_data->root = g_object_ref (root);
 
   /* Set up D-Bus connection and register bus name */
   dbus_error_init (&error);
 
   /* Set up D-Bus connection and register bus name */
   dbus_error_init (&error);
@@ -388,6 +387,15 @@ adaptor_init (gint * argc, gchar ** argv[])
   dbus_connection_setup_with_g_main (spi_global_app_data->bus,
                                      g_main_context_default ());
 
   dbus_connection_setup_with_g_main (spi_global_app_data->bus,
                                      g_main_context_default ());
 
+  /* 
+   * Create the leasing, register and cache objects.
+   * The order is important here, the cache depends on the
+   * register object.
+   */
+  spi_global_register = g_object_new (SPI_REGISTER_TYPE, NULL);
+  spi_global_leasing  = g_object_new (SPI_LEASING_TYPE, NULL);
+  spi_global_cache    = g_object_new (SPI_CACHE_TYPE, NULL);
+
   /* Get D-Bus introspection directory */
   introspection_directory = (char *) g_getenv ("ATSPI_INTROSPECTION_PATH");
   if (introspection_directory == NULL)
   /* Get D-Bus introspection directory */
   introspection_directory = (char *) g_getenv ("ATSPI_INTROSPECTION_PATH");
   if (introspection_directory == NULL)
@@ -398,7 +406,7 @@ adaptor_init (gint * argc, gchar ** argv[])
     droute_new (spi_global_app_data->bus, introspection_directory);
 
   treepath = droute_add_one (spi_global_app_data->droute,
     droute_new (spi_global_app_data->bus, introspection_directory);
 
   treepath = droute_add_one (spi_global_app_data->droute,
-                             "/org/at_spi/cache", NULL);
+                             "/org/at_spi/cache", spi_global_cache);
 
   accpath = droute_add_many (spi_global_app_data->droute,
                              "/org/at_spi/accessible",
 
   accpath = droute_add_many (spi_global_app_data->droute,
                              "/org/at_spi/accessible",
@@ -406,14 +414,6 @@ adaptor_init (gint * argc, gchar ** argv[])
                              (DRouteGetDatumFunction)
                              spi_global_register_path_to_object);
 
                              (DRouteGetDatumFunction)
                              spi_global_register_path_to_object);
 
-  /* 
-   * Create the leasing, register and cache objects.
-   * The order is important here, the cache depends on the
-   * register object.
-   */
-  spi_global_register = g_object_new (SPI_REGISTER_TYPE, NULL);
-  spi_global_leasing  = g_object_new (SPI_LEASING_TYPE, NULL);
-  spi_global_cache    = g_object_new (SPI_CACHE_TYPE, NULL);
 
   /* Register all interfaces with droute and set up application accessible db */
   spi_initialize_cache (treepath);
 
   /* Register all interfaces with droute and set up application accessible db */
   spi_initialize_cache (treepath);
@@ -435,7 +435,7 @@ adaptor_init (gint * argc, gchar ** argv[])
   /* Register methods to send D-Bus signals on certain ATK events */
   spi_atk_register_event_listeners ();
 
   /* Register methods to send D-Bus signals on certain ATK events */
   spi_atk_register_event_listeners ();
 
-#ifdef __ATK_PLUG_H__
+#ifdef SPI_ATK_PLUG_SOCKET
   /* Hook our plug-and socket functions */
   install_plug_hooks ();
 #endif
   /* Hook our plug-and socket functions */
   install_plug_hooks ();
 #endif
index e97046b..7dc9e45 100644 (file)
@@ -285,7 +285,7 @@ emit_event (AtkObject  *obj,
 
   gchar *cname, *t;
   DBusMessage *sig;
 
   gchar *cname, *t;
   DBusMessage *sig;
-  DBusMessageIter iter;
+  DBusMessageIter iter, iter_struct;
   
   if (!klass) klass = "";
   if (!major) major = "";
   
   if (!klass) klass = "";
   if (!major) major = "";
@@ -304,6 +304,7 @@ emit_event (AtkObject  *obj,
 
   dbus_message_iter_init_append(sig, &iter);
 
 
   dbus_message_iter_init_append(sig, &iter);
 
+  spi_object_append_reference (&iter, spi_global_app_data->root);
   dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &minor);
   dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail1);
   dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail2);
   dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &minor);
   dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail1);
   dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail2);
index f16ff7f..38f905c 100644 (file)
@@ -98,19 +98,21 @@ fi
 AC_SUBST(EXTRA_SOCKET_LIBS)
 
 dnl find sizes & alignments
 AC_SUBST(EXTRA_SOCKET_LIBS)
 
 dnl find sizes & alignments
-#orig_CPPFLAGS=$CPPFLAGS
-#CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS"
-#DBIND_CHECK_ALIGNOF(char)
-#DBIND_CHECK_ALIGNOF(dbus_bool_t)
-#DBIND_CHECK_ALIGNOF(dbus_int16_t)
-#DBIND_CHECK_ALIGNOF(dbus_int32_t)
-#DBIND_CHECK_ALIGNOF(dbus_int64_t)
-#DBIND_CHECK_ALIGNOF(double)
-#DBIND_CHECK_ALIGNOF(dbind_pointer)
-#DBIND_CHECK_ALIGNOF(dbind_struct)
-#CPPFLAGS=$orig_CPPFLAGS 
+orig_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS"
+DBIND_CHECK_ALIGNOF(char)
+DBIND_CHECK_ALIGNOF(dbus_bool_t)
+DBIND_CHECK_ALIGNOF(dbus_int16_t)
+DBIND_CHECK_ALIGNOF(dbus_int32_t)
+DBIND_CHECK_ALIGNOF(dbus_int64_t)
+DBIND_CHECK_ALIGNOF(double)
+DBIND_CHECK_ALIGNOF(dbind_pointer)
+DBIND_CHECK_ALIGNOF(dbind_struct)
+CPPFLAGS=$orig_CPPFLAGS 
 
 AC_CONFIG_FILES([Makefile
 
 AC_CONFIG_FILES([Makefile
+                dbind/dbind-config.h
+                dbind/Makefile
                 droute/Makefile
                 common/Makefile
                 atk-adaptor/Makefile
                 droute/Makefile
                 common/Makefile
                 atk-adaptor/Makefile
index 5ab1478..8c7bd51 100644 (file)
@@ -249,6 +249,8 @@ impl_prop_GetAll (DBusMessage *message,
     gchar *iface;
 
     void  *datum = path_get_datum (path, pathstr);
     gchar *iface;
 
     void  *datum = path_get_datum (path, pathstr);
+    if (!datum)
+       return NULL;
 
     dbus_error_init (&error);
     if (!dbus_message_get_args
 
     dbus_error_init (&error);
     if (!dbus_message_get_args
@@ -299,6 +301,7 @@ impl_prop_GetSet (DBusMessage *message,
     StrPair pair;
     PropertyPair *prop_funcs = NULL;
 
     StrPair pair;
     PropertyPair *prop_funcs = NULL;
 
+    void *datum;
 
     dbus_error_init (&error);
     if (!dbus_message_get_args (message,
 
     dbus_error_init (&error);
     if (!dbus_message_get_args (message,
@@ -316,9 +319,13 @@ impl_prop_GetSet (DBusMessage *message,
     if (!prop_funcs)
         return dbus_message_new_error (message, DBUS_ERROR_FAILED, "Property unavailable");
 
     if (!prop_funcs)
         return dbus_message_new_error (message, DBUS_ERROR_FAILED, "Property unavailable");
 
+    datum = path_get_datum (path, pathstr);
+    if (!datum)
+       return NULL;
+
     if (get && prop_funcs->get)
       {
     if (get && prop_funcs->get)
       {
-        void *datum = path_get_datum (path, pathstr);
+        
         DBusMessageIter iter;
 
         _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr);
         DBusMessageIter iter;
 
         _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr);
@@ -333,7 +340,6 @@ impl_prop_GetSet (DBusMessage *message,
       }
     else if (!get && prop_funcs->set)
       {
       }
     else if (!get && prop_funcs->set)
       {
-        void *datum = path_get_datum (path, pathstr);
         DBusMessageIter iter;
 
         _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr);
         DBusMessageIter iter;
 
         _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr);
@@ -484,15 +490,20 @@ handle_other (DBusConnection *bus,
     DRouteFunction func;
     DBusMessage *reply = NULL;
 
     DRouteFunction func;
     DBusMessage *reply = NULL;
 
+    void *datum;
+
     pair.one = iface;
     pair.two = member;
 
     _DROUTE_DEBUG ("DRoute (handle other): %s|%s on %s\n", member, iface, pathstr);
 
     pair.one = iface;
     pair.two = member;
 
     _DROUTE_DEBUG ("DRoute (handle other): %s|%s on %s\n", member, iface, pathstr);
 
+    datum = path_get_datum (path, pathstr);
+    if (!datum)
+       return result;
+
     func = (DRouteFunction) g_hash_table_lookup (path->methods, &pair);
     if (func != NULL)
       {
     func = (DRouteFunction) g_hash_table_lookup (path->methods, &pair);
     if (func != NULL)
       {
-        void *datum = path_get_datum (path, pathstr);
 
         reply = (func) (bus, message, datum);
 
 
         reply = (func) (bus, message, datum);