Exemplo n.º 1
0
/*
 * Find an event using the name and signature in the given registry. RCU read
 * side lock MUST be acquired before calling this function and as long as the
 * event reference is kept by the caller.
 *
 * On success, the event pointer is returned else NULL.
 */
struct ust_registry_event *ust_registry_find_event(
		struct ust_registry_channel *chan, char *name, char *sig)
{
	struct lttng_ht_node_u64 *node;
	struct lttng_ht_iter iter;
	struct ust_registry_event *event = NULL;
	struct ust_registry_event key;

	assert(chan);
	assert(name);
	assert(sig);

	/* Setup key for the match function. */
	strncpy(key.name, name, sizeof(key.name));
	key.name[sizeof(key.name) - 1] = '\0';
	key.signature = sig;

	cds_lfht_lookup(chan->ht->ht, chan->ht->hash_fct(&key, lttng_ht_seed),
			chan->ht->match_fct, &key, &iter.iter);
	node = lttng_ht_iter_get_node_u64(&iter);
	if (!node) {
		goto end;
	}
	event = caa_container_of(node, struct ust_registry_event, node);

end:
	return event;
}
Exemplo n.º 2
0
/*
 * Lookup function in hashtable.
 */
void lttng_ht_lookup(struct lttng_ht *ht, void *key,
		struct lttng_ht_iter *iter)
{
	assert(ht);
	assert(ht->ht);

	cds_lfht_lookup(ht->ht, ht->hash_fct(key, lttng_ht_seed),
			ht->match_fct, key, &iter->iter);
}
Exemplo n.º 3
0
UA_StatusCode UA_NodeStore_remove(UA_NodeStore *ns, const UA_NodeId *nodeid) {
    hash_t nhash = hash(nodeid);
    struct cds_lfht_iter iter;

    rcu_read_lock();
    /* If this fails, then the node has already been removed. */
    cds_lfht_lookup(ns->ht, nhash, compare, &nodeid, &iter);
    if(!iter.node || cds_lfht_del(ns->ht, iter.node) != 0) {
        rcu_read_unlock();
        return UA_STATUSCODE_BADNODEIDUNKNOWN;
    }

    struct nodeEntry *entry = (struct nodeEntry*) ((uintptr_t)iter.node - offsetof(struct nodeEntry, htn)); 
    call_rcu(&entry->rcu_head, markDead);
    rcu_read_unlock();

    return UA_STATUSCODE_GOOD;
}
Exemplo n.º 4
0
const UA_Node * UA_NodeStore_get(const UA_NodeStore *ns, const UA_NodeId *nodeid) {
    hash_t nhash = hash(nodeid);
    struct cds_lfht_iter iter;

    rcu_read_lock();
    cds_lfht_lookup(ns->ht, nhash, compare, nodeid, &iter);
    struct nodeEntry *found_entry = (struct nodeEntry *)cds_lfht_iter_get_node(&iter);

    if(!found_entry) {
        rcu_read_unlock();
        return NULL;
    }

    /* This is done within a read-lock. The node will not be marked dead within a read-lock. */
    uatomic_inc(&found_entry->refcount);
    rcu_read_unlock();
    return &found_entry->node;
}
Exemplo n.º 5
0
UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode, UA_Node *node,
                                   const UA_Node **inserted) {
    size_t nodesize;
    /* Copy the node into the entry. Then reset the original node. It shall no longer be used. */
    switch(node->nodeClass) {
    case UA_NODECLASS_OBJECT:
        nodesize = sizeof(UA_ObjectNode);
        break;
    case UA_NODECLASS_VARIABLE:
        nodesize = sizeof(UA_VariableNode);
        break;
    case UA_NODECLASS_METHOD:
        nodesize = sizeof(UA_MethodNode);
        break;
    case UA_NODECLASS_OBJECTTYPE:
        nodesize = sizeof(UA_ObjectTypeNode);
        break;
    case UA_NODECLASS_VARIABLETYPE:
        nodesize = sizeof(UA_VariableTypeNode);
        break;
    case UA_NODECLASS_REFERENCETYPE:
        nodesize = sizeof(UA_ReferenceTypeNode);
        break;
    case UA_NODECLASS_DATATYPE:
        nodesize = sizeof(UA_DataTypeNode);
        break;
    case UA_NODECLASS_VIEW:
        nodesize = sizeof(UA_ViewNode);
        break;
    default:
        return UA_STATUSCODE_BADINTERNALERROR;
    }

    struct nodeEntry *newEntry;
    if(!(newEntry = UA_malloc(sizeof(struct nodeEntry) - sizeof(UA_Node) + nodesize)))
        return UA_STATUSCODE_BADOUTOFMEMORY;
    memcpy((void*)&newEntry->node, node, nodesize);

    cds_lfht_node_init(&newEntry->htn);
    newEntry->refcount = ALIVE_BIT;
    if(inserted) // increase the counter before adding the node
        newEntry->refcount++;

    hash_t h = hash(&node->nodeId);
    struct cds_lfht_iter iter;
    rcu_read_lock();
    cds_lfht_lookup(ns->ht, h, compare, &node->nodeId, &iter);

    /* No node found that can be replaced */
    if(!iter.node) {
        rcu_read_unlock();
        UA_free(newEntry);
        return UA_STATUSCODE_BADNODEIDUNKNOWN;
    }

    struct nodeEntry *oldEntry = (struct nodeEntry*) ((uintptr_t)iter.node - offsetof(struct nodeEntry, htn)); 
    /* The node we found is obsolete*/
    if(&oldEntry->node != oldNode) {
        rcu_read_unlock();
        UA_free(newEntry);
        return UA_STATUSCODE_BADINTERNALERROR;
    }

    /* The old node is replaced by a managed node. */
    if(cds_lfht_replace(ns->ht, &iter, h, compare, &node->nodeId, &newEntry->htn) != 0) {
        /* Replacing failed. Maybe the node got replaced just before this thread tried to.*/
        rcu_read_unlock();
        UA_free(newEntry);
        return UA_STATUSCODE_BADINTERNALERROR;
    }
        
    /* If an entry got replaced, mark it as dead. */
    call_rcu(&oldEntry->rcu_head, markDead);
    rcu_read_unlock();
    UA_free(node);

    if(inserted)
        *inserted = &newEntry->node;
    return UA_STATUSCODE_GOOD;
}