cds_lfht_replace: add checks for old/new node hash/value match
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 21 Dec 2011 13:53:48 +0000 (08:53 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 21 Dec 2011 14:05:07 +0000 (09:05 -0500)
Also initialize reverse hash in replace.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
rculfhash.c
urcu/rculfhash.h

index 75e5ece96c9edb3e462b861fe61e682561d7a1c4..1eda2dd858981477041fcdcee252c78d224127c2 100644 (file)
@@ -1517,11 +1517,22 @@ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht,
        }
 }
 
-int cds_lfht_replace(struct cds_lfht *ht, struct cds_lfht_iter *old_iter,
+int cds_lfht_replace(struct cds_lfht *ht,
+               struct cds_lfht_iter *old_iter,
+               unsigned long hash,
+               cds_lfht_match_fct match,
+               const void *key,
                struct cds_lfht_node *new_node)
 {
        unsigned long size;
 
+       new_node->reverse_hash = bit_reverse_ulong((unsigned long) hash);
+       if (!old_iter->node)
+               return -ENOENT;
+       if (caa_unlikely(old_iter->node->reverse_hash != new_node->reverse_hash))
+               return -EINVAL;
+       if (caa_unlikely(!match(old_iter->node, key)))
+               return -EINVAL;
        size = rcu_dereference(ht->size);
        return _cds_lfht_replace(ht, size, old_iter->node, old_iter->next,
                        new_node);
index b33ede09cfa664388b9f094e78d60a6161936bba..96dc5a023aa6d4958b24bf316269463ed114b62a 100644 (file)
@@ -325,11 +325,16 @@ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht,
  * cds_lfht_replace - replace a node pointer to by iter within hash table.
  * @ht: the hash table.
  * @old_iter: the iterator position of the node to replace.
- * @now_node: the new node to try using for replacement.
+ * @hash: the node's hash.
+ * @match: the key match function.
+ * @key: the node's key.
+ * @new_node: the new node to use as replacement.
  *
  * Return 0 if replacement is successful, negative value otherwise.
- * Replacing a NULL old node or an already removed node will fail with a
- * negative value.
+ * Replacing a NULL old node or an already removed node will fail with
+ * -ENOENT.
+ * If the hash or value of the node to replace and the new node differ,
+ * this function returns -EINVAL without proceeding to the replacement.
  * Old node can be looked up with cds_lfht_lookup and cds_lfht_next.
  * RCU read-side lock must be held between lookup and replacement.
  * Call with rcu_read_lock held.
@@ -348,7 +353,11 @@ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht,
  * guarantee that a combination of add_replace and add_unique updates
  * will never generate duplicated keys.
  */
-int cds_lfht_replace(struct cds_lfht *ht, struct cds_lfht_iter *old_iter,
+int cds_lfht_replace(struct cds_lfht *ht,
+               struct cds_lfht_iter *old_iter,
+               unsigned long hash,
+               cds_lfht_match_fct match,
+               const void *key,
                struct cds_lfht_node *new_node);
 
 /*
This page took 0.027338 seconds and 4 git commands to generate.