int b1_handle_acquire(B1Handle **handlep, B1Peer *peer, uint64_t handle_id) { B1Handle *handle; CRBNode **slot, *p; int r; assert(handlep); assert(peer); 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_id, &handle); if (r < 0) return r; c_rbtree_add(&peer->handles, p, slot, &handle->rb); } else { handle = c_container_of(p, B1Handle, rb); b1_handle_ref(handle); b1_handle_release(handle); } *handlep = handle; return 0; }
/** * b1_node_new() - create a new node for a peer * @peer: the owning peer, or null * @nodep: pointer to the new node object * @userdata: userdata to associate with the node * * A node is the recipient of messages, and. Nodes are allocated lazily in the * kernel, so it is not guaranteed to be a kernel equivalent to the userspace * object at all times. A node is associated with at most one peer, and for a * lazily created node it may not be associated with any peer until it is * actually created, at which point it is associated with the creating peer. * * Return: 0 on success, and a negative error code on failure. */ _c_public_ int b1_node_new(B1Peer *peer, B1Node **nodep, void *userdata) { _c_cleanup_(b1_node_freep) B1Node *node = NULL; int r; r = b1_node_new_internal(peer, &node, userdata, BUS1_HANDLE_INVALID, NULL); if (r < 0) return r; r = b1_handle_new(peer, BUS1_HANDLE_INVALID, &node->handle); if (r < 0) return r; node->handle->node = node; *nodep = node; node = NULL; return 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; }
/** * b1_node_new() - create a new node for a peer * @peer: the owning peer * @nodep: pointer to the new node object * * Return: 0 on success, and a negative error code on failure. */ _c_public_ int b1_node_new(B1Peer *peer, B1Node **nodep) { _c_cleanup_(b1_node_freep) B1Node *node = NULL; int r; node = calloc(1, sizeof(*node)); if (!node) return -ENOMEM; node->id = BUS1_HANDLE_INVALID; node->owner = b1_peer_ref(peer); c_rbnode_init(&node->rb_nodes); r = b1_handle_new(peer, &node->handle); if (r < 0) return r; node->handle->node = node; *nodep = node; node = NULL; return 0; }