Fix another bug related to marked CHashPtrs.
authorRobert Haas <rhaas@postgresql.org>
Fri, 27 Jul 2012 18:19:47 +0000 (18:19 +0000)
committerRobert Haas <rhaas@postgresql.org>
Tue, 27 Jan 2015 02:24:23 +0000 (02:24 +0000)
src/backend/utils/hash/chash.c

index 4855bc8aceff2dae8a5108d706e5400db810a2e9..700a2e93278f34c131eec68fdaf39ac384cf7847 100644 (file)
@@ -463,6 +463,7 @@ retry:
                 * in the table.  Even for a quite modestly size table this is likely
                 * to exceed the number of CPU cores.
                 */
+               Assert(!CHashPtrIsMarked(scan.target));
                nnew->next = scan.target;
                if (!__sync_bool_compare_and_swap(scan.pointer_to_target,
                                                                                  scan.target, new))
@@ -557,6 +558,9 @@ CHashDelete(CHashTable table, void *entry)
  * case, res->pointer_to_target will a pointer to the address where the value
  * of target was found.  res->target_node will be a pointer to the address of
  * the CHashNode with offset res->target, unless res->target is invalid.
+ *
+ * NB: If you change this function, make sure to adjust CHashBucketCleanup
+ * similarly.
  */
 static void
 CHashBucketScan(CHashTable table,
@@ -622,7 +626,7 @@ zap:
                                 */
                                CHashAddToGarbage(table, hashcode & table->bucket_mask,
                                                                  target);
-                               target = next;
+                               target = CHashPtrUnmark(next);
                                continue;
                        }
                        else
@@ -948,7 +952,7 @@ retry:
                                /* We removed the item. */
                                CHashAddToGarbage(table, hashcode & table->bucket_mask,
                                                                  target);
-                               target = next;
+                               target = CHashPtrUnmark(next);
                                continue;
                        }
                        else