diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index cab7ae74ca..cfbebeb31d 100644 --- a/src/backend/storage/ipc/dsm.c +++ b/src/backend/storage/ipc/dsm.c @@ -569,22 +569,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;