summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--dbus/dbus-connection.c46
-rw-r--r--dbus/dbus-connection.h4
-rw-r--r--dbus/dbus-object-tree.c37
-rw-r--r--dbus/dbus-object-tree.h1
5 files changed, 82 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index ccca8a8e..a9328da2 100644
--- 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
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index 608634d2..b8e67c14 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -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);
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index c5dee7f0..bbdbcda8 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -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);
diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c
index 24e402a2..8430b323 100644
--- a/dbus/dbus-object-tree.c
+++ b/dbus/dbus-object-tree.c
@@ -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;
}
diff --git a/dbus/dbus-object-tree.h b/dbus/dbus-object-tree.h
index 5d44bbe2..21d8b5f1 100644
--- a/dbus/dbus-object-tree.h
+++ b/dbus/dbus-object-tree.h
@@ -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);