Пример #1
0
/**
 * b1_node_free() - destroy a node
 * @node:               node to destroy
 *
 * This destroys the given node and releases all linked resources. This implies
 * a call to b1_node_destroy(), if not already done by the caller.
 *
 * Return: NULL is returned.
 */
_c_public_ B1Node *b1_node_free(B1Node *node) {
        CRBNode *n;

        if (!node)
                return NULL;

        assert(node->owner);

        b1_node_release(node);

        while ((n = c_rbtree_first(&node->implementations))) {
                B1Implementation *implementation = c_container_of(n, B1Implementation, rb);

                c_rbtree_remove(&node->implementations, n);
                b1_interface_unref(implementation->interface);
                free(implementation);
        }

        /* if the node name is set, it means this node is owned by a message or
         * peer object, which will be responsibly for cleaning it up */
        if (!node->name && node->id != BUS1_HANDLE_INVALID) {
                b1_node_destroy(node);
                c_rbtree_remove(&node->owner->nodes, &node->rb);
        }

        b1_peer_unref(node->owner);
        free(node);

        return NULL;
}
Пример #2
0
/* verify that all API calls are exported */
static void test_api(void) {
        CRBTree t = {};
        CRBNode n = C_RBNODE_INIT(n);

        assert(!c_rbnode_is_linked(&n));

        /* init, is_linked, add, remove, remove_init */

        c_rbtree_add(&t, NULL, &t.root, &n);
        assert(c_rbnode_is_linked(&n));

        c_rbtree_remove_init(&t, &n);
        assert(!c_rbnode_is_linked(&n));

        c_rbtree_add(&t, NULL, &t.root, &n);
        assert(c_rbnode_is_linked(&n));

        c_rbtree_remove(&t, &n);
        assert(c_rbnode_is_linked(&n)); /* @n wasn't touched */

        c_rbnode_init(&n);
        assert(!c_rbnode_is_linked(&n));

        /* first, last, leftmost, rightmost, next, prev */

        assert(!c_rbtree_first(&t));
        assert(!c_rbtree_last(&t));
        assert(&n == c_rbnode_leftmost(&n));
        assert(&n == c_rbnode_rightmost(&n));
        assert(!c_rbnode_next(&n));
        assert(!c_rbnode_prev(&n));
}
Пример #3
0
/**
 * b1_handle_unref() - release reference
 * @handle:             handle to release reference to, or NULL
 *
 * Release a single reference to an handle. If this is the last reference, the
 * handle is freed.
 *
 * If NULL is passed, this is a no-op.
 *
 * Return: NULL is returned.
 */
_c_public_ B1Handle *b1_handle_unref(B1Handle *handle) {
        if (!handle)
                return NULL;

        assert(handle->n_ref > 0);

        if (--handle->n_ref > 0)
                return NULL;

        b1_handle_release(handle);

        if (handle->id != BUS1_HANDLE_INVALID) {
                assert(handle->holder);
                c_rbtree_remove(&handle->holder->handles, &handle->rb);
        }

        b1_peer_unref(handle->holder);
        free(handle);

        return NULL;
}
Пример #4
0
/* run some pseudo-random tests on the tree */
static void test_shuffle(void) {
        CRBNode *nodes[256];
        CRBTree t = {};
        unsigned int i, j;
        size_t n;

        /* allocate and initialize all nodes */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
                nodes[i] = malloc(sizeof(*nodes[i]));
                assert(nodes[i]);
                c_rbnode_init(nodes[i]);
        }

        /* shuffle nodes and validate *empty* tree */
        shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
        n = validate(&t);
        assert(n == 0);

        /* add all nodes and validate after each insertion */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
                insert(&t, nodes[i]);
                n = validate(&t);
                assert(n == i + 1);
        }

        /* shuffle nodes again */
        shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));

        /* remove all nodes (in different order) and validate on each round */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
                c_rbtree_remove(&t, nodes[i]);
                n = validate(&t);
                assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
                c_rbnode_init(nodes[i]);
        }

        /* shuffle nodes and validate *empty* tree again */
        shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
        n = validate(&t);
        assert(n == 0);

        /* add all nodes again */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
                insert(&t, nodes[i]);
                n = validate(&t);
                assert(n == i + 1);
        }

        /* 4 times, remove half of the nodes and add them again */
        for (j = 0; j < 4; ++j) {
                /* shuffle nodes again */
                shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));

                /* remove half of the nodes */
                for (i = 0; i < sizeof(nodes) / sizeof(*nodes) / 2; ++i) {
                        c_rbtree_remove(&t, nodes[i]);
                        n = validate(&t);
                        assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
                        c_rbnode_init(nodes[i]);
                }

                /* shuffle the removed half */
                shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes) / 2);

                /* add the removed half again */
                for (i = 0; i < sizeof(nodes) / sizeof(*nodes) / 2; ++i) {
                        insert(&t, nodes[i]);
                        n = validate(&t);
                        assert(n == sizeof(nodes) / sizeof(*nodes) / 2 + i + 1);
                }
        }

        /* shuffle nodes again */
        shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));

        /* remove all */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
                c_rbtree_remove(&t, nodes[i]);
                n = validate(&t);
                assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
                c_rbnode_init(nodes[i]);
        }

        /* free nodes again */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i)
                free(nodes[i]);
}