Commit 789a5b34 authored by Bruce Momjian's avatar Bruce Momjian

Move attached to shared memory out into a separate function for clarity.

parent 075a0078
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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); ...@@ -47,6 +47,8 @@ static void IpcMemoryDetach(int status, Datum shmaddr);
static void IpcMemoryDelete(int status, Datum shmId); static void IpcMemoryDelete(int status, Datum shmId);
static void *PrivateMemoryCreate(uint32 size); static void *PrivateMemoryCreate(uint32 size);
static void PrivateMemoryDelete(int status, Datum memaddr); 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) ...@@ -297,72 +299,48 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
IpcMemoryKey NextShmemSegID; IpcMemoryKey NextShmemSegID;
void *memAddress; void *memAddress;
PGShmemHeader *hdr; PGShmemHeader *hdr;
IpcMemoryId shmid;
/* Room for a header? */ /* Room for a header? */
Assert(size > MAXALIGN(sizeof(PGShmemHeader))); Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
if (ExecBackend && UsedShmemSegID != 0) /* Just attach and return the pointer */
NextShmemSegID = UsedShmemSegID; if (ExecBackend && UsedShmemSegAddr != NULL && !makePrivate)
else
NextShmemSegID = port * 1000 + 1;
for (;;NextShmemSegID++)
{ {
IpcMemoryId shmid; if ((hdr = (PGShmemHeader *) memAddress = PGSharedMemoryAttach(
UsedShmemSegID, &shmid, UsedShmemSegAddr)) == NULL)
/* 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)
{ {
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)); (int) UsedShmemSegID, UsedShmemSegAddr, strerror(errno));
proc_exit(1); proc_exit(1);
} }
return hdr;
}
if (!ExecBackend || UsedShmemSegAddr == NULL) /* Create shared memory */
{
/* Try to create new segment */ NextShmemSegID = port * 1000 + 1;
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 */
hdr = (PGShmemHeader *) memAddress; for (;;NextShmemSegID++)
if (hdr->magic != PGShmemMagic) {
/* Special case if creating a private segment --- just malloc() it */
if (makePrivate)
{ {
shmdt(memAddress); memAddress = PrivateMemoryCreate(size);
continue; /* segment belongs to a non-Postgres app */ break;
} }
/* Successfully attached to shared memory, which is all we wanted */ /* Try to create new segment */
if (ExecBackend && UsedShmemSegAddr != NULL) memAddress = InternalIpcMemoryCreate(NextShmemSegID, size);
break; if (memAddress)
break; /* successful create and attach */
/* Check shared memory and possibly remove and recreate */ /* 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, * If I am not the creator and it belongs to an extant process,
* continue. * continue.
...@@ -401,31 +379,60 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port) ...@@ -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 = (PGShmemHeader *) memAddress;
hdr->creatorPID = getpid();
hdr->magic = PGShmemMagic;
if (!ExecBackend || makePrivate || UsedShmemSegAddr == NULL) /*
{ * Initialize space allocation status for segment.
/* */
* OK, we created a new segment. Mark it as created by this process. hdr->totalsize = size;
* The order of assignments here is critical so that another Postgres hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
* 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));
}
if (ExecBackend && !makePrivate && UsedShmemSegAddr == NULL)
if (ExecBackend && UsedShmemSegAddr == NULL && !makePrivate)
{ {
UsedShmemSegAddr = memAddress; UsedShmemSegAddr = memAddress;
UsedShmemSegID = NextShmemSegID; 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; return hdr;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment