]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Move attached to shared memory out into a separate function for clarity.
authorBruce Momjian <bruce@momjian.us>
Thu, 8 May 2003 19:17:07 +0000 (19:17 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 8 May 2003 19:17:07 +0000 (19:17 +0000)
src/backend/port/sysv_shmem.c

index 9454c3e92cc6981022c596e1439dbc6dc47b1aa1..ffe5bfa268a1a74c4906204221ace799d98191bb 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/port/sysv_shmem.c,v 1.9 2003/05/08 14:49:03 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/port/sysv_shmem.c,v 1.10 2003/05/08 19:17:07 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,6 +47,8 @@ static void IpcMemoryDetach(int status, Datum shmaddr);
 static void IpcMemoryDelete(int status, Datum shmId);
 static void *PrivateMemoryCreate(uint32 size);
 static void PrivateMemoryDelete(int status, Datum memaddr);
+static PGShmemHeader *PGSharedMemoryAttach(IpcMemoryKey key,
+                                                                               IpcMemoryId *shmid, void *addr);
 
 
 /*
@@ -297,72 +299,48 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
        IpcMemoryKey NextShmemSegID;
        void       *memAddress;
        PGShmemHeader *hdr;
+       IpcMemoryId shmid;
 
        /* Room for a header? */
        Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
 
-       if (ExecBackend && UsedShmemSegID != 0)
-               NextShmemSegID = UsedShmemSegID;
-       else
-               NextShmemSegID = port * 1000 + 1;
-
-       for (;;NextShmemSegID++)
+       /* Just attach and return the pointer */
+       if (ExecBackend && UsedShmemSegAddr != NULL && !makePrivate)
        {
-               IpcMemoryId shmid;
-
-               /* Special case if creating a private segment --- just malloc() it */
-               if (makePrivate)
-               {
-                       memAddress = PrivateMemoryCreate(size);
-                       break;
-               }
-
-               /* If attach to fixed address, only try once */
-               if (ExecBackend && UsedShmemSegAddr != NULL && NextShmemSegID != UsedShmemSegID)
+               if ((hdr = (PGShmemHeader *) memAddress = PGSharedMemoryAttach(
+                                               UsedShmemSegID, &shmid, UsedShmemSegAddr)) == NULL)
                {
-                       fprintf(stderr, "Unable to attach to memory at fixed address: shmget(key=%d, addr=%p) failed: %s\n",
+                       fprintf(stderr, "Unable to attach to proper memory at fixed address: shmget(key=%d, addr=%p) failed: %s\n",
                                (int) UsedShmemSegID, UsedShmemSegAddr, strerror(errno));
                        proc_exit(1);
                }
+               return hdr;
+       }
 
-               if (!ExecBackend || UsedShmemSegAddr == NULL)
-               {
-                       /* Try to create new segment */
-                       memAddress = InternalIpcMemoryCreate(NextShmemSegID, size);
-                       if (memAddress)
-                               break;                          /* successful create and attach */
-               }
-
-               /* See if it looks to be leftover from a dead Postgres process */
-               shmid = shmget(NextShmemSegID, sizeof(PGShmemHeader), 0);
-               if (shmid < 0)
-                       continue;                       /* failed: must be some other app's */
-
-               /* use intimate shared memory on SPARC Solaris */
-               memAddress = shmat(shmid, UsedShmemSegAddr,
-#if defined(solaris) && defined(__sparc__)
-                               SHM_SHARE_MMU
-#else
-                               0
-#endif
-                       );
-
-               if (memAddress == (void *) -1)
-                       continue;                       /* failed: must be some other app's */
+       /* Create shared memory */
+       
+       NextShmemSegID = port * 1000 + 1;
 
-               hdr = (PGShmemHeader *) memAddress;
-               if (hdr->magic != PGShmemMagic)
+       for (;;NextShmemSegID++)
+       {
+               /* Special case if creating a private segment --- just malloc() it */
+               if (makePrivate)
                {
-                       shmdt(memAddress);
-                       continue;                       /* segment belongs to a non-Postgres app */
+                       memAddress = PrivateMemoryCreate(size);
+                       break;
                }
 
-               /* Successfully attached to shared memory, which is all we wanted */
-               if (ExecBackend && UsedShmemSegAddr != NULL)
-                       break;
+               /* Try to create new segment */
+               memAddress = InternalIpcMemoryCreate(NextShmemSegID, size);
+               if (memAddress)
+                       break;                          /* successful create and attach */
 
                /* Check shared memory and possibly remove and recreate */
                        
+               if ((hdr = (PGShmemHeader *) memAddress = PGSharedMemoryAttach(
+                                               NextShmemSegID, &shmid, UsedShmemSegAddr)) == NULL)
+                       continue;                       /* can't attach, not one of mine */
+
                /*
                 * If I am not the creator and it belongs to an extant process,
                 * continue.
@@ -401,31 +379,60 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
                 */
        }
 
+       /*
+        * OK, we created a new segment.  Mark it as created by this process.
+        * The order of assignments here is critical so that another Postgres
+        * process can't see the header as valid but belonging to an invalid
+        * PID!
+        */
        hdr = (PGShmemHeader *) memAddress;
+       hdr->creatorPID = getpid();
+       hdr->magic = PGShmemMagic;
 
-       if (!ExecBackend || makePrivate || UsedShmemSegAddr == NULL)
-       {
-               /*
-                * OK, we created a new segment.  Mark it as created by this process.
-                * The order of assignments here is critical so that another Postgres
-                * process can't see the header as valid but belonging to an invalid
-                * PID!
-                */
-               hdr->creatorPID = getpid();
-               hdr->magic = PGShmemMagic;
-       
-               /*
-                * Initialize space allocation status for segment.
-                */
-               hdr->totalsize = size;
-               hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
-       }
+       /*
+        * Initialize space allocation status for segment.
+        */
+       hdr->totalsize = size;
+       hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
 
-       if (ExecBackend && !makePrivate && UsedShmemSegAddr == NULL)
+       
+       if (ExecBackend && UsedShmemSegAddr == NULL && !makePrivate)
        {
                UsedShmemSegAddr = memAddress;
                UsedShmemSegID = NextShmemSegID;
        }
+       
+       return hdr;
+}
+
+
+/*
+ *     Attach to shared memory and make sure it has a Postgres header
+ */
+static PGShmemHeader *
+PGSharedMemoryAttach(IpcMemoryKey key, IpcMemoryId *shmid, void *addr)
+{
+       PGShmemHeader *hdr;
+
+       if ((*shmid = shmget(key, sizeof(PGShmemHeader), 0)) < 0)
+               return NULL;
 
+       hdr = (PGShmemHeader *) shmat(*shmid, UsedShmemSegAddr,
+#if defined(solaris) && defined(__sparc__)
+                       /* use intimate shared memory on SPARC Solaris */
+                       SHM_SHARE_MMU
+#else
+                       0
+#endif
+               );
+
+       if (hdr == (PGShmemHeader *) -1)
+               return NULL;                    /* failed: must be some other app's */
+
+       if (hdr->magic != PGShmemMagic)
+       {
+               shmdt(hdr);
+               return NULL;                    /* segment belongs to a non-Postgres app */
+       }
        return hdr;
 }