2003-09-06 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Sat, 6 Sep 2003 18:21:00 +0000 (18:21 +0000)
committerHavoc Pennington <hp@redhat.com>
Sat, 6 Sep 2003 18:21:00 +0000 (18:21 +0000)
* dbus/dbus-connection.c (dbus_connection_register_fallback): add this
(dbus_connection_register_object_path): make this not handle
messages to paths below the given path

ChangeLog
dbus/dbus-connection.c
dbus/dbus-connection.h
dbus/dbus-object-tree.c
dbus/dbus-object-tree.h

index ccca8a8..a9328da 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2003-09-06  Havoc Pennington  <hp@pobox.com>
+
+       * dbus/dbus-connection.c (dbus_connection_register_fallback): add this
+       (dbus_connection_register_object_path): make this not handle
+       messages to paths below the given path
+
 2003-09-03  Havoc Pennington  <hp@pobox.com>
 
        * test/glib/Makefile.am: add this with random glib-linked test
index 608634d..b8e67c1 100644 (file)
@@ -3049,8 +3049,8 @@ dbus_connection_remove_filter (DBusConnection            *connection,
 }
 
 /**
- * Registers a handler for a given subsection of the object hierarchy.
- * The given vtable handles messages at or below the given path.
+ * Registers a handler for a given path in the object hierarchy.
+ * The given vtable handles messages sent to exactly the given path.
  *
  *
  * @param connection the connection
@@ -3074,7 +3074,47 @@ dbus_connection_register_object_path (DBusConnection              *connection,
 
   CONNECTION_LOCK (connection);
 
-  retval = _dbus_object_tree_register (connection->objects, path, vtable,
+  retval = _dbus_object_tree_register (connection->objects,
+                                       FALSE,
+                                       path, vtable,
+                                       user_data);
+
+  CONNECTION_UNLOCK (connection);
+
+  return retval;
+}
+
+/**
+ * Registers a fallback handler for a given subsection of the object
+ * hierarchy.  The given vtable handles messages at or below the given
+ * path. You can use this to establish a default message handling
+ * policy for a whole "subdirectory."
+ *
+ *
+ * @param connection the connection
+ * @param path #NULL-terminated array of path elements
+ * @param vtable the virtual table
+ * @param user_data data to pass to functions in the vtable
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_connection_register_fallback (DBusConnection              *connection,
+                                   const char                 **path,
+                                   const DBusObjectPathVTable  *vtable,
+                                   void                        *user_data)
+{
+  dbus_bool_t retval;
+  
+  _dbus_return_val_if_fail (connection != NULL, FALSE);
+  _dbus_return_val_if_fail (path != NULL, FALSE);
+  _dbus_return_val_if_fail (path[0] != NULL, FALSE);
+  _dbus_return_val_if_fail (vtable != NULL, FALSE);
+
+  CONNECTION_LOCK (connection);
+
+  retval = _dbus_object_tree_register (connection->objects,
+                                       TRUE,
+                                       path, vtable,
                                        user_data);
 
   CONNECTION_UNLOCK (connection);
index c5dee7f..bbdbcda 100644 (file)
@@ -229,6 +229,10 @@ dbus_bool_t dbus_connection_register_object_path   (DBusConnection
                                                     const char                 **path,
                                                     const DBusObjectPathVTable  *vtable,
                                                     void                        *user_data);
+dbus_bool_t dbus_connection_register_fallback      (DBusConnection              *connection,
+                                                    const char                 **path,
+                                                    const DBusObjectPathVTable  *vtable,
+                                                    void                        *user_data);
 void        dbus_connection_unregister_object_path (DBusConnection              *connection,
                                                     const char                 **path);
 
index 24e402a..8430b32 100644 (file)
@@ -71,6 +71,7 @@ struct DBusObjectSubtree
   DBusObjectSubtree                **subtrees;
   int                                n_subtrees;
   unsigned int                       subtrees_sorted : 1;
+  unsigned int                       invoke_as_fallback : 1;
   char                               name[1]; /**< Allocated as large as necessary */
 };
 
@@ -93,7 +94,8 @@ _dbus_object_tree_new (DBusConnection *connection)
   tree->root = _dbus_object_subtree_new ("/", NULL, NULL);
   if (tree->root == NULL)
     goto oom;
-
+  tree->root->invoke_as_fallback = TRUE;
+  
   return tree;
 
  oom:
@@ -221,7 +223,8 @@ find_subtree_recurse (DBusObjectSubtree  *subtree,
               next = find_subtree_recurse (subtree->subtrees[i],
                                            &path[1], return_deepest_match,
                                            create_if_not_found, index_in_parent);
-              if (next == NULL)
+              if (next == NULL &&
+                  subtree->invoke_as_fallback)
                 {
 #if VERBOSE_FIND
                   _dbus_verbose ("  no deeper match found, returning %s\n",
@@ -293,7 +296,7 @@ find_subtree_recurse (DBusObjectSubtree  *subtree,
                                    create_if_not_found, index_in_parent);
     }
   else
-    return return_deepest_match ? subtree : NULL;
+    return (return_deepest_match && subtree->invoke_as_fallback) ? subtree : NULL;
 }
 
 static DBusObjectSubtree*
@@ -339,6 +342,7 @@ ensure_subtree (DBusObjectTree *tree,
  * Registers a new subtree in the global object tree.
  *
  * @param tree the global object tree
+ * @param fallback #TRUE to handle messages to children of this path
  * @param path NULL-terminated array of path elements giving path to subtree
  * @param vtable the vtable used to traverse this subtree
  * @param user_data user data to pass to methods in the vtable
@@ -346,6 +350,7 @@ ensure_subtree (DBusObjectTree *tree,
  */
 dbus_bool_t
 _dbus_object_tree_register (DBusObjectTree              *tree,
+                            dbus_bool_t                  fallback,
                             const char                 **path,
                             const DBusObjectPathVTable  *vtable,
                             void                        *user_data)
@@ -360,17 +365,22 @@ _dbus_object_tree_register (DBusObjectTree              *tree,
   if (subtree == NULL)
     return FALSE;
 
+#ifndef DBUS_DISABLE_CHECKS
   if (subtree->message_function != NULL)
     {
       _dbus_warn ("A handler is already registered for the path starting with path[0] = \"%s\"\n",
                   path[0] ? path[0] : "null");
       return FALSE;
     }
+#else
+  _dbus_assert (subtree->message_function == NULL);
+#endif
 
   subtree->message_function = vtable->message_function;
   subtree->unregister_function = vtable->unregister_function;
   subtree->user_data = user_data;
-
+  subtree->invoke_as_fallback = fallback != FALSE;
+  
   return TRUE;
 }
 
@@ -395,6 +405,7 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree          *tree,
 
   subtree = find_subtree (tree, path, &i);
 
+#ifndef DBUS_DISABLE_CHECKS
   if (subtree == NULL)
     {
       _dbus_warn ("Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered\n",
@@ -402,6 +413,9 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree          *tree,
                   path[1] ? path[1] : "null");
       return;
     }
+#else
+  _dbus_assert (subtree != NULL);
+#endif
 
   _dbus_assert (subtree->parent == NULL ||
                 (i >= 0 && subtree->parent->subtrees[i] == subtree));
@@ -523,7 +537,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree          *tree,
   DBusList *link;
   DBusHandlerResult result;
   DBusObjectSubtree *subtree;
-
+  
 #if 0
   _dbus_verbose ("Dispatch of message by object path\n");
 #endif
@@ -540,10 +554,10 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree          *tree,
       _dbus_verbose ("No path field in message\n");
       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
-
+  
   /* Find the deepest path that covers the path in the message */
   subtree = find_handler (tree, (const char**) path);
-
+  
   /* Build a list of all paths that cover the path in the message */
 
   list = NULL;
@@ -884,7 +898,7 @@ do_register (DBusObjectTree *tree,
   tree_test_data[i].handler_unregistered = FALSE;
   tree_test_data[i].path = path;
 
-  if (!_dbus_object_tree_register (tree, path,
+  if (!_dbus_object_tree_register (tree, TRUE, path,
                                    &vtable,
                                    &tree_test_data[i]))
     return FALSE;
@@ -1269,7 +1283,12 @@ object_tree_test_iteration (void *data)
   
  out:
   if (tree)
-    _dbus_object_tree_unref (tree);
+    {
+      /* test ref */
+      _dbus_object_tree_ref (tree);
+      _dbus_object_tree_unref (tree);
+      _dbus_object_tree_unref (tree);
+    }
 
   return TRUE;
 }
index 5d44bbe..21d8b5f 100644 (file)
@@ -34,6 +34,7 @@ void            _dbus_object_tree_ref   (DBusObjectTree *tree);
 void            _dbus_object_tree_unref (DBusObjectTree *tree);
 
 dbus_bool_t       _dbus_object_tree_register              (DBusObjectTree              *tree,
+                                                           dbus_bool_t                  fallback,
                                                            const char                 **path,
                                                            const DBusObjectPathVTable  *vtable,
                                                            void                        *user_data);