X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-object-tree.c;h=172c9d95dc81f66fdabb028ac2204682e97e992f;hb=67f9cca382df0d03adfe6b619aa613d103fa77f6;hp=da8d8c26067afe513c0f7703948607c019c95a50;hpb=98ad8a8ec6626f7f5c78915b6bdf2be688b4839f;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c index da8d8c2..172c9d9 100644 --- a/dbus/dbus-object-tree.c +++ b/dbus/dbus-object-tree.c @@ -1,7 +1,7 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-object-tree.c DBusObjectTree (internals of DBusConnection) * - * Copyright (C) 2003 Red Hat Inc. + * Copyright (C) 2003, 2005 Red Hat Inc. * * Licensed under the Academic Free License version 2.1 * @@ -17,9 +17,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ + +#include #include "dbus-object-tree.h" #include "dbus-connection-internal.h" #include "dbus-internals.h" @@ -74,7 +76,7 @@ struct DBusObjectSubtree void *user_data; /**< Data for functions */ DBusObjectSubtree **subtrees; /**< Child nodes */ int n_subtrees; /**< Number of child nodes */ - unsigned int subtrees_sorted : 1; /**< Whether children are sorted */ + int max_subtrees; /**< Number of allocated entries in subtrees */ unsigned int invoke_as_fallback : 1; /**< Whether to invoke message_function when child nodes don't handle the message */ char name[1]; /**< Allocated as large as necessary */ }; @@ -152,36 +154,6 @@ _dbus_object_tree_unref (DBusObjectTree *tree) } } -static int -subtree_cmp (DBusObjectSubtree *subtree_a, - DBusObjectSubtree *subtree_b) -{ - return strcmp (subtree_a->name, subtree_b->name); -} - -static int -subtree_qsort_cmp (const void *a, - const void *b) -{ - DBusObjectSubtree **subtree_a_p = (void*) a; - DBusObjectSubtree **subtree_b_p = (void*) b; - - return subtree_cmp (*subtree_a_p, *subtree_b_p); -} - -static void -ensure_sorted (DBusObjectSubtree *subtree) -{ - if (subtree->subtrees && !subtree->subtrees_sorted) - { - qsort (subtree->subtrees, - subtree->n_subtrees, - sizeof (DBusObjectSubtree*), - subtree_qsort_cmp); - subtree->subtrees_sorted = TRUE; - } -} - /** Set to 1 to get a bunch of debug spew about finding the * subtree nodes */ @@ -194,7 +166,7 @@ find_subtree_recurse (DBusObjectSubtree *subtree, int *index_in_parent, dbus_bool_t *exact_match) { - int i; + int i, j; dbus_bool_t return_deepest_match; return_deepest_match = exact_match != NULL; @@ -217,22 +189,18 @@ find_subtree_recurse (DBusObjectSubtree *subtree, subtree->name, path[0]); #endif - ensure_sorted (subtree); - - /* FIXME we should do a binary search here instead - * of O(n) - */ - i = 0; - while (i < subtree->n_subtrees) + j = subtree->n_subtrees; + while (i < j) { - int v; + int k, v; - v = strcmp (path[0], subtree->subtrees[i]->name); + k = (i + j) / 2; + v = strcmp (path[0], subtree->subtrees[k]->name); #if VERBOSE_FIND _dbus_verbose (" %s cmp %s = %d\n", - path[0], subtree->subtrees[i]->name, + path[0], subtree->subtrees[k]->name, v); #endif @@ -241,16 +209,16 @@ find_subtree_recurse (DBusObjectSubtree *subtree, if (index_in_parent) { #if VERBOSE_FIND - _dbus_verbose (" storing parent index %d\n", i); + _dbus_verbose (" storing parent index %d\n", k); #endif - *index_in_parent = i; + *index_in_parent = k; } if (return_deepest_match) { DBusObjectSubtree *next; - next = find_subtree_recurse (subtree->subtrees[i], + next = find_subtree_recurse (subtree->subtrees[k], &path[1], create_if_not_found, index_in_parent, exact_match); if (next == NULL && @@ -268,19 +236,20 @@ find_subtree_recurse (DBusObjectSubtree *subtree, return next; } else - return find_subtree_recurse (subtree->subtrees[i], + return find_subtree_recurse (subtree->subtrees[k], &path[1], create_if_not_found, index_in_parent, exact_match); } else if (v < 0) { - goto not_found; + j = k; + } + else + { + i = k + 1; } - - ++i; } - not_found: #if VERBOSE_FIND _dbus_verbose (" no match found, current tree %s, create_if_not_found = %d\n", subtree->name, create_if_not_found); @@ -289,8 +258,7 @@ find_subtree_recurse (DBusObjectSubtree *subtree, if (create_if_not_found) { DBusObjectSubtree* child; - DBusObjectSubtree **new_subtrees; - int new_n_subtrees; + int child_pos, new_n_subtrees; #if VERBOSE_FIND _dbus_verbose (" creating subtree %s\n", @@ -302,25 +270,41 @@ find_subtree_recurse (DBusObjectSubtree *subtree, if (child == NULL) return NULL; - /* FIXME we should do the "double alloc each time" standard thing */ new_n_subtrees = subtree->n_subtrees + 1; - new_subtrees = dbus_realloc (subtree->subtrees, - new_n_subtrees * sizeof (DBusObjectSubtree*)); - if (new_subtrees == NULL) + if (new_n_subtrees > subtree->max_subtrees) { - child->unregister_function = NULL; - child->message_function = NULL; - _dbus_object_subtree_unref (child); - return NULL; + int new_max_subtrees; + DBusObjectSubtree **new_subtrees; + + new_max_subtrees = subtree->max_subtrees == 0 ? 1 : 2 * subtree->max_subtrees; + new_subtrees = dbus_realloc (subtree->subtrees, + new_max_subtrees * sizeof (DBusObjectSubtree*)); + if (new_subtrees == NULL) + { + _dbus_object_subtree_unref (child); + return NULL; + } + subtree->subtrees = new_subtrees; + subtree->max_subtrees = new_max_subtrees; } - new_subtrees[subtree->n_subtrees] = child; + /* The binary search failed, so i == j points to the + place the child should be inserted. */ + child_pos = i; + _dbus_assert (child_pos < new_n_subtrees && + new_n_subtrees <= subtree->max_subtrees); + if (child_pos + 1 < new_n_subtrees) + { + memmove (&subtree->subtrees[child_pos+1], + &subtree->subtrees[child_pos], + (new_n_subtrees - child_pos - 1) * + sizeof subtree->subtrees[0]); + } + subtree->subtrees[child_pos] = child; + if (index_in_parent) - *index_in_parent = subtree->n_subtrees; - subtree->subtrees_sorted = FALSE; + *index_in_parent = child_pos; subtree->n_subtrees = new_n_subtrees; - subtree->subtrees = new_subtrees; - child->parent = subtree; return find_subtree_recurse (child, @@ -373,6 +357,9 @@ find_handler (DBusObjectTree *tree, _dbus_verbose ("Looking for deepest handler\n"); #endif _dbus_assert (exact_match != NULL); + + *exact_match = FALSE; /* ensure always initialized */ + return find_subtree_recurse (tree->root, path, FALSE, NULL, exact_match); } @@ -386,6 +373,8 @@ ensure_subtree (DBusObjectTree *tree, return find_subtree_recurse (tree->root, path, TRUE, NULL, NULL); } +static char *flatten_path (const char **path); + /** * Registers a new subtree in the global object tree. * @@ -394,14 +383,17 @@ ensure_subtree (DBusObjectTree *tree, * @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 - * @returns #FALSE if not enough memory + * @param error address where an error can be returned + * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or + * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported */ dbus_bool_t _dbus_object_tree_register (DBusObjectTree *tree, dbus_bool_t fallback, const char **path, const DBusObjectPathVTable *vtable, - void *user_data) + void *user_data, + DBusError *error) { DBusObjectSubtree *subtree; @@ -411,24 +403,33 @@ _dbus_object_tree_register (DBusObjectTree *tree, subtree = ensure_subtree (tree, path); if (subtree == NULL) - return FALSE; + { + _DBUS_SET_OOM (error); + 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"); + if (error != NULL) + { + char *complete_path = flatten_path (path); + + dbus_set_error (error, DBUS_ERROR_OBJECT_PATH_IN_USE, + "A handler is already registered for %s", + complete_path ? complete_path + : "(cannot represent path: out of memory!)"); + + dbus_free (complete_path); + } + 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; } @@ -451,6 +452,9 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, _dbus_assert (path != NULL); + unregister_function = NULL; + user_data = NULL; + subtree = find_subtree (tree, path, &i); #ifndef DBUS_DISABLE_CHECKS @@ -459,7 +463,7 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, _dbus_warn ("Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered\n", path[0] ? path[0] : "null", path[1] ? path[1] : "null"); - return; + goto unlock; } #else _dbus_assert (subtree != NULL); @@ -495,6 +499,7 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, } subtree = NULL; +unlock: connection = tree->connection; /* Unlock and call application code */ @@ -503,6 +508,7 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, #endif { _dbus_connection_ref_unlocked (connection); + _dbus_verbose ("unlock\n"); _dbus_connection_unlock (connection); } @@ -607,9 +613,9 @@ _dbus_object_tree_list_registered_unlocked (DBusObjectTree *tree, } static DBusHandlerResult -handle_default_introspect_unlocked (DBusObjectTree *tree, - DBusMessage *message, - const char **path) +handle_default_introspect_and_unlock (DBusObjectTree *tree, + DBusMessage *message, + const char **path) { DBusString xml; DBusHandlerResult result; @@ -618,22 +624,45 @@ handle_default_introspect_unlocked (DBusObjectTree *tree, DBusMessage *reply; DBusMessageIter iter; const char *v_STRING; + dbus_bool_t already_unlocked; /* We have the connection lock here */ + + already_unlocked = FALSE; _dbus_verbose (" considering default Introspect() handler...\n"); reply = NULL; if (!dbus_message_is_method_call (message, - DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE, + DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + { +#ifdef DBUS_BUILD_TESTS + if (tree->connection) +#endif + { + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (tree->connection); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } _dbus_verbose (" using default Introspect() handler!\n"); if (!_dbus_string_init (&xml)) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + { +#ifdef DBUS_BUILD_TESTS + if (tree->connection) +#endif + { + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (tree->connection); + } + + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } result = DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -673,13 +702,26 @@ handle_default_introspect_unlocked (DBusObjectTree *tree, if (tree->connection) #endif { - if (!_dbus_connection_send_unlocked (tree->connection, reply, NULL)) + already_unlocked = TRUE; + + if (!_dbus_connection_send_and_unlock (tree->connection, reply, NULL)) goto out; } result = DBUS_HANDLER_RESULT_HANDLED; out: +#ifdef DBUS_BUILD_TESTS + if (tree->connection) +#endif + { + if (!already_unlocked) + { + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (tree->connection); + } + } + _dbus_string_free (&xml); dbus_free_string_array (children); if (reply) @@ -703,7 +745,8 @@ handle_default_introspect_unlocked (DBusObjectTree *tree, */ DBusHandlerResult _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, - DBusMessage *message) + DBusMessage *message, + dbus_bool_t *found_object) { char **path; dbus_bool_t exact_match; @@ -722,7 +765,10 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - _dbus_connection_unlock (tree->connection); + { + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (tree->connection); + } _dbus_verbose ("No memory to get decomposed path\n"); @@ -734,7 +780,10 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - _dbus_connection_unlock (tree->connection); + { + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (tree->connection); + } _dbus_verbose ("No path field in message\n"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -743,6 +792,9 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, /* Find the deepest path that covers the path in the message */ subtree = find_handler (tree, (const char**) path, &exact_match); + if (found_object) + *found_object = !!subtree; + /* Build a list of all paths that cover the path in the message */ list = NULL; @@ -797,7 +849,10 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - _dbus_connection_unlock (tree->connection); + { + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (tree->connection); + } /* FIXME you could unregister the subtree in another thread * before we invoke the callback, and I can't figure out a @@ -826,14 +881,19 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, { /* This hardcoded default handler does a minimal Introspect() */ - result = handle_default_introspect_unlocked (tree, message, - (const char**) path); + result = handle_default_introspect_and_unlock (tree, message, + (const char**) path); } - + else + { #ifdef DBUS_BUILD_TESTS - if (tree->connection) + if (tree->connection) #endif - _dbus_connection_unlock (tree->connection); + { + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (tree->connection); + } + } while (list != NULL) { @@ -848,6 +908,36 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, } /** + * Looks up the data passed to _dbus_object_tree_register() for a + * handler at the given path. + * + * @param tree the global object tree + * @param path NULL-terminated array of path elements giving path to subtree + * @returns the object's user_data or #NULL if none found + */ +void* +_dbus_object_tree_get_user_data_unlocked (DBusObjectTree *tree, + const char **path) +{ + dbus_bool_t exact_match; + DBusObjectSubtree *subtree; + + _dbus_assert (tree != NULL); + _dbus_assert (path != NULL); + + /* Find the deepest path that covers the path in the message */ + subtree = find_handler (tree, (const char**) path, &exact_match); + + if ((subtree == NULL) || !exact_match) + { + _dbus_verbose ("No object at specified path found\n"); + return NULL; + } + + return subtree->user_data; +} + +/** * Allocates a subtree object. * * @param name name to duplicate. @@ -864,7 +954,7 @@ allocate_subtree_object (const char *name) len = strlen (name); - subtree = dbus_malloc (front_padding + (len + 1)); + subtree = dbus_malloc0 (MAX (front_padding + (len + 1), sizeof (DBusObjectSubtree))); if (subtree == NULL) return NULL; @@ -901,28 +991,29 @@ _dbus_object_subtree_new (const char *name, } subtree->user_data = user_data; - subtree->refcount.value = 1; + _dbus_atomic_inc (&subtree->refcount); subtree->subtrees = NULL; subtree->n_subtrees = 0; - subtree->subtrees_sorted = TRUE; + subtree->max_subtrees = 0; subtree->invoke_as_fallback = FALSE; return subtree; oom: - if (subtree) - { - dbus_free (subtree); - } - return NULL; } static DBusObjectSubtree * _dbus_object_subtree_ref (DBusObjectSubtree *subtree) { - _dbus_assert (subtree->refcount.value > 0); +#ifdef DBUS_DISABLE_ASSERT _dbus_atomic_inc (&subtree->refcount); +#else + dbus_int32_t old_value; + + old_value = _dbus_atomic_inc (&subtree->refcount); + _dbus_assert (old_value > 0); +#endif return subtree; } @@ -930,9 +1021,12 @@ _dbus_object_subtree_ref (DBusObjectSubtree *subtree) static void _dbus_object_subtree_unref (DBusObjectSubtree *subtree) { - _dbus_assert (subtree->refcount.value > 0); + dbus_int32_t old_value; + + old_value = _dbus_atomic_dec (&subtree->refcount); + _dbus_assert (old_value > 0); - if (_dbus_atomic_dec (&subtree->refcount) == 1) + if (old_value == 1) { _dbus_assert (subtree->unregister_function == NULL); _dbus_assert (subtree->message_function == NULL); @@ -966,7 +1060,10 @@ _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - _dbus_connection_unlock (tree->connection); + { + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (tree->connection); + } return result; } @@ -996,6 +1093,7 @@ _dbus_decompose_path (const char* data, int i, j, comp; _dbus_assert (data != NULL); + _dbus_assert (path != NULL); #if VERBOSE_DECOMPOSE _dbus_verbose ("Decomposing path \"%s\"\n", @@ -1008,6 +1106,7 @@ _dbus_decompose_path (const char* data, i = 0; while (i < len) { + _dbus_assert (data[i] != '\0'); if (data[i] == '/') n_components += 1; ++i; @@ -1071,10 +1170,6 @@ _dbus_decompose_path (const char* data, /** @} */ -#ifdef DBUS_BUILD_TESTS -#include "dbus-test.h" -#include - static char* flatten_path (const char **path) { @@ -1119,6 +1214,13 @@ flatten_path (const char **path) } +#ifdef DBUS_BUILD_TESTS + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#include "dbus-test.h" +#include + typedef enum { STR_EQUAL, @@ -1141,9 +1243,9 @@ path_contains (const char **container, if (container[i] == NULL) return STR_PREFIX; /* container ran out, child continues; - * thus the container is a parent of the - * child. - */ + * thus the container is a parent of the + * child. + */ _dbus_assert (container[i] != NULL); _dbus_assert (child[i] != NULL); @@ -1152,8 +1254,8 @@ path_contains (const char **container, if (v != 0) return STR_DIFFERENT; /* they overlap until here and then are different, - * not overlapping - */ + * not overlapping + */ ++i; } @@ -1242,7 +1344,7 @@ do_register (DBusObjectTree *tree, { DBusObjectPathVTable vtable = { test_unregister_function, test_message_function, NULL }; - + tree_test_data[i].message_handled = FALSE; tree_test_data[i].handler_unregistered = FALSE; tree_test_data[i].handler_fallback = fallback; @@ -1250,9 +1352,13 @@ do_register (DBusObjectTree *tree, if (!_dbus_object_tree_register (tree, fallback, path, &vtable, - &tree_test_data[i])) + &tree_test_data[i], + NULL)) return FALSE; + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path) == + &tree_test_data[i]); + return TRUE; } @@ -1289,7 +1395,7 @@ do_test_dispatch (DBusObjectTree *tree, ++j; } - result = _dbus_object_tree_dispatch_and_unlock (tree, message); + result = _dbus_object_tree_dispatch_and_unlock (tree, message, NULL); if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) goto oom; @@ -1659,6 +1765,7 @@ object_tree_test_iteration (void *data) goto out; _dbus_object_tree_unregister_and_unlock (tree, path0); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path0) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); @@ -1671,6 +1778,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path1); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path1) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); @@ -1683,6 +1791,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path2); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path2) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); @@ -1695,6 +1804,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path3); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path3) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); @@ -1707,6 +1817,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path4); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path4) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); @@ -1719,6 +1830,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path5); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path5) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); @@ -1731,6 +1843,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path6); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path6) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); @@ -1743,6 +1856,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path7); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path7) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); @@ -1755,6 +1869,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path8); + _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path8) == NULL); _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); @@ -1845,4 +1960,6 @@ _dbus_object_tree_test (void) return TRUE; } +#endif /* !DOXYGEN_SHOULD_SKIP_THIS */ + #endif /* DBUS_BUILD_TESTS */