diff options
author | Robert Haas <rhaas@postgresql.org> | 2014-05-06 13:37:46 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2014-05-06 13:40:34 -0400 |
commit | e0124230ba2b6778671f26b06af0d8d04bcb4d1c (patch) | |
tree | 9c4ebf589629668060d32312476d198e626992de /src | |
parent | 4335c958154c39ef99a38dc953b3f803b13a1048 (diff) | |
download | postgresql-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.c | 15 |
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); |