aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/storage/ipc/dsm.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 36904d2676f..58b42298a72 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -597,22 +597,20 @@ dsm_attach(dsm_handle h)
nitems = dsm_control->nitems;
for (i = 0; i < nitems; ++i)
{
- /* If the reference count is 0, the slot is actually unused. */
- if (dsm_control->item[i].refcnt == 0)
+ /*
+ * If the reference count is 0, the slot is actually unused. If the
+ * reference count is 1, the slot is still in use, but the segment is
+ * in the process of going away; even if the handle matches, another
+ * slot may already have started using the same handle value by
+ * coincidence so we have to keep searching.
+ */
+ if (dsm_control->item[i].refcnt <= 1)
continue;
/* If the handle doesn't match, it's not the slot we want. */
if (dsm_control->item[i].handle != seg->handle)
continue;
- /*
- * If the reference count is 1, the slot is still in use, but the
- * segment is in the process of going away. Treat that as if we
- * didn't find a match.
- */
- if (dsm_control->item[i].refcnt == 1)
- break;
-
/* Otherwise we've found a match. */
dsm_control->item[i].refcnt++;
seg->control_slot = i;