Don't bogusly propagate delete-marks.
authorRobert Haas <[email protected]>
Fri, 27 Jul 2012 17:29:26 +0000 (17:29 +0000)
committerRobert Haas <[email protected]>
Fri, 27 Jul 2012 17:31:57 +0000 (17:31 +0000)
src/backend/utils/hash/chash.c

index a076da07c25c57622ce018d708632066d04284ea..4855bc8aceff2dae8a5108d706e5400db810a2e9 100644 (file)
@@ -519,9 +519,10 @@ CHashDelete(CHashTable table, void *entry)
                                                                                          CHashPtrMark(next)))
                {
                        /* Deletion is done; attempt to remove node from list. */
+                       Assert(!CHashPtrIsMarked(scan.target));
                        if (__sync_bool_compare_and_swap(scan.pointer_to_target,
                                                                                         scan.target,
-                                                                                        next))
+                                                                                        CHashPtrUnmark(next)))
                                CHashAddToGarbage(table, bucket, scan.target);
                        else
                                cleanup_scan = true;
@@ -607,7 +608,9 @@ retry:
                if (CHashPtrIsMarked(next))
                {
 zap:
-                       if (__sync_bool_compare_and_swap(pointer_to_target, target, next))
+                       if (__sync_bool_compare_and_swap(pointer_to_target,
+                                                                                        target,
+                                                                                        CHashPtrUnmark(next)))
                        {
                                /*
                                 * No one else can possibly have modified target_node->next,
@@ -938,7 +941,9 @@ retry:
                /* If element is delete-marked, try to remove it. */
                if (CHashPtrIsMarked(next))
                {
-                       if (__sync_bool_compare_and_swap(pointer_to_target, target, next))
+                       if (__sync_bool_compare_and_swap(pointer_to_target,
+                                                                                        target,
+                                                                                        CHashPtrUnmark(next)))
                        {
                                /* We removed the item. */
                                CHashAddToGarbage(table, hashcode & table->bucket_mask,