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;
 }