Fix logic bug in dsm_attach().
authorRobert Haas <rhaas@postgresql.org>
Tue, 6 May 2014 17:37:46 +0000 (13:37 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 6 May 2014 17:40:34 +0000 (13:40 -0400)
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

src/backend/storage/ipc/dsm.c

index 733fa5f7bd3de6f447af717aca7affafbe7aaf88..a5c008463a9de9fd2df34982e793bcfcc7241425 100644 (file)
@@ -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);