Exemple #1
0
int b1_handle_acquire(B1Peer *peer, B1Handle **handlep, uint64_t handle_id) {
        B1Handle *handle;
        CRBNode **slot, *p;
        int r;

        assert(peer);
        assert(handlep);

        if (handle_id == BUS1_HANDLE_INVALID) {
                *handlep = NULL;
                return 0;
        }

        slot = c_rbtree_find_slot(&peer->handles, handles_compare, &handle_id, &p);
        if (slot) {
                r = b1_handle_new(peer, &handle);
                if (r < 0)
                        return r;

                handle->ref_kernel = (CRef)C_REF_INIT;
                handle->live = true;
                handle->id = handle_id;

                c_rbtree_add(&peer->handles, p, slot, &handle->rb);
        } else {
                handle = c_container_of(p, B1Handle, rb);
                if (handle->live) {
                        c_ref_inc(&handle->ref_kernel);
                        /* reusing existing handle, drop redundant reference from kernel */
                        r = bus1_peer_handle_release(handle->holder->peer, handle->id);
                        if (r < 0)
                                return r;
                } else {
                        handle->ref_kernel = (CRef)C_REF_INIT;
                        handle->live = true;
                }
                c_ref_inc(&handle->ref);
        }

        *handlep = handle;
        return 0;
}
Exemple #2
0
/**
 * b1_node_destroy() - destroy node
 * @node:               node to destroy, or NULL
 *
 * Destroy the node in the kernel, regardless of any handles held by other
 * peers. If any peers still hold handles, they will receive node destruction
 * notifications for this node.
 *
 * If NULL is passed, this is a no-op.
 *
 * Return: 0 on success, and a negative error code on failure.
 */
_c_public_ int b1_node_destroy(B1Node *node) {
        struct bus1_cmd_nodes_destroy nodes_destroy = {
                .ptr_nodes = (uintptr_t)&node->id,
                .n_nodes = 1,
        };

        if (!node)
                return 0;

        return bus1_peer_nodes_destroy(node->owner->peer, &nodes_destroy);
}

/**
 * b1_handle_ref() - acquire reference
 * @handle:             handle to acquire reference to, or NULL
 *
 * Acquire a new reference to a handle. The caller must already own a reference
 * themself.
 *
 * If NULL is passed, this is a no-op.
 *
 * Return: @handle is returned.
 */
_c_public_ B1Handle *b1_handle_ref(B1Handle *handle) {
        B1Handle *new_handle;
        int r;

        if (handle) {
                if (!handle->live) {
                        r = b1_handle_transfer(handle, handle->holder, &new_handle);
                        assert(r >= 0);
                        assert(new_handle == handle);
                } else {
                        c_ref_inc(&handle->ref_kernel);
                        c_ref_inc(&handle->ref);
                }
        }

        return handle;
}
Exemple #3
0
/**
 * b1_peer_ref() - acquire reference
 * @peer:               peer to acquire reference to, or NULL
 *
 * Return: @peer is returned.
 */
_c_public_ B1Peer *b1_peer_ref(B1Peer *peer) {
        if (peer)
                c_ref_inc(&peer->ref);

        return peer;
}