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
This commit is contained in:
Havoc Pennington 2003-09-06 18:21:00 +00:00
parent d7f8a9510f
commit 666fe95480
5 changed files with 82 additions and 12 deletions

View file

@ -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

View 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);

View 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);

View 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;
}

View 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);