aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2014-05-06 13:37:46 -0400
committerRobert Haas <rhaas@postgresql.org>2014-05-06 13:40:34 -0400
commite0124230ba2b6778671f26b06af0d8d04bcb4d1c (patch)
tree9c4ebf589629668060d32312476d198e626992de /src
parent4335c958154c39ef99a38dc953b3f803b13a1048 (diff)
downloadpostgresql-e0124230ba2b6778671f26b06af0d8d04bcb4d1c.tar.gz
postgresql-e0124230ba2b6778671f26b06af0d8d04bcb4d1c.zip
Fix logic bug in dsm_attach().
The previous coding would potentially cause attaching to segment A to fail if segment B was at the same time in the process of going away. Andres Freund, with a comment tweak by me
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/ipc/dsm.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 733fa5f7bd3..a5c008463a9 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -566,6 +566,10 @@ dsm_attach(dsm_handle h)
if (dsm_control->item[i].refcnt == 0)
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
@@ -574,13 +578,10 @@ dsm_attach(dsm_handle h)
if (dsm_control->item[i].refcnt == 1)
break;
- /* Otherwise, if the descriptor matches, we've found a match. */
- if (dsm_control->item[i].handle == seg->handle)
- {
- dsm_control->item[i].refcnt++;
- seg->control_slot = i;
- break;
- }
+ /* Otherwise we've found a match. */
+ dsm_control->item[i].refcnt++;
+ seg->control_slot = i;
+ break;
}
LWLockRelease(DynamicSharedMemoryControlLock);