summaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/ipc')
-rw-r--r--src/backend/storage/ipc/ipci.c50
-rw-r--r--src/backend/storage/ipc/pmsignal.c6
-rw-r--r--src/backend/storage/ipc/procarray.c13
-rw-r--r--src/backend/storage/ipc/shmem.c43
-rw-r--r--src/backend/storage/ipc/sinval.c6
-rw-r--r--src/backend/storage/ipc/sinvaladt.c30
6 files changed, 100 insertions, 48 deletions
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 0761a8fdf51..48ef94a3ecb 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.77 2005/06/17 22:32:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.78 2005/08/20 23:26:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,36 +61,44 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
if (!IsUnderPostmaster)
{
- int size;
+ Size size;
int numSemas;
/*
* Size of the Postgres shared-memory block is estimated via
* moderately-accurate estimates for the big hogs, plus 100K for
* the stuff that's too small to bother with estimating.
+ *
+ * We take some care during this phase to ensure that the total
+ * size request doesn't overflow size_t. If this gets through,
+ * we don't need to be so careful during the actual allocation
+ * phase.
*/
- size = hash_estimate_size(SHMEM_INDEX_SIZE, sizeof(ShmemIndexEnt));
- size += BufferShmemSize();
- size += LockShmemSize();
- size += ProcGlobalShmemSize();
- size += XLOGShmemSize();
- size += CLOGShmemSize();
- size += SUBTRANSShmemSize();
- size += TwoPhaseShmemSize();
- size += MultiXactShmemSize();
- size += LWLockShmemSize();
- size += ProcArrayShmemSize();
- size += SInvalShmemSize(MaxBackends);
- size += FreeSpaceShmemSize();
- size += BgWriterShmemSize();
+ size = 100000;
+ size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
+ sizeof(ShmemIndexEnt)));
+ size = add_size(size, BufferShmemSize());
+ size = add_size(size, LockShmemSize());
+ size = add_size(size, ProcGlobalShmemSize());
+ size = add_size(size, XLOGShmemSize());
+ size = add_size(size, CLOGShmemSize());
+ size = add_size(size, SUBTRANSShmemSize());
+ size = add_size(size, TwoPhaseShmemSize());
+ size = add_size(size, MultiXactShmemSize());
+ size = add_size(size, LWLockShmemSize());
+ size = add_size(size, ProcArrayShmemSize());
+ size = add_size(size, SInvalShmemSize());
+ size = add_size(size, FreeSpaceShmemSize());
+ size = add_size(size, BgWriterShmemSize());
#ifdef EXEC_BACKEND
- size += ShmemBackendArraySize();
+ size = add_size(size, ShmemBackendArraySize());
#endif
- size += 100000;
+
/* might as well round it off to a multiple of a typical page size */
- size += 8192 - (size % 8192);
+ size = add_size(size, 8192 - (size % 8192));
- elog(DEBUG3, "invoking IpcMemoryCreate(size=%d)", size);
+ elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
+ (unsigned long) size);
/*
* Create the shmem segment
@@ -163,7 +171,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
/*
* Set up shared-inval messaging
*/
- CreateSharedInvalidationState(MaxBackends);
+ CreateSharedInvalidationState();
/*
* Set up free-space map
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index fbc5cf5666b..a916688717c 100644
--- a/src/backend/storage/ipc/pmsignal.c
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.18 2004/12/31 22:00:56 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.19 2005/08/20 23:26:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -48,7 +48,9 @@ PMSignalInit(void)
bool found;
PMSignalFlags = (sig_atomic_t *)
- ShmemInitStruct("PMSignalFlags", NUM_PMSIGNALS * sizeof(sig_atomic_t), &found);
+ ShmemInitStruct("PMSignalFlags",
+ NUM_PMSIGNALS * sizeof(sig_atomic_t),
+ &found);
if (!found)
MemSet(PMSignalFlags, 0, NUM_PMSIGNALS * sizeof(sig_atomic_t));
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 87b1228ae6d..f2950bece30 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -23,7 +23,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.5 2005/08/20 01:26:36 ishii Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.6 2005/08/20 23:26:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -81,11 +81,16 @@ static void DisplayXidCache(void);
/*
* Report shared-memory space needed by CreateSharedProcArray.
*/
-int
+Size
ProcArrayShmemSize(void)
{
- return MAXALIGN(offsetof(ProcArrayStruct, procs) +
- (MaxBackends + max_prepared_xacts) * sizeof(PGPROC *));
+ Size size;
+
+ size = offsetof(ProcArrayStruct, procs);
+ size = add_size(size, mul_size(sizeof(PGPROC *),
+ add_size(MaxBackends, max_prepared_xacts)));
+
+ return size;
}
/*
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 9af059139e7..76b3ef26cc4 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.84 2005/05/29 04:23:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.85 2005/08/20 23:26:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -141,8 +141,8 @@ InitShmemAllocation(void *seghdr, bool init)
void *
ShmemAlloc(Size size)
{
- uint32 newStart;
- uint32 newFree;
+ Size newStart;
+ Size newFree;
void *newSpace;
/* use volatile pointer to prevent code rearrangement */
@@ -415,3 +415,40 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
SpinLockRelease(ShmemIndexLock);
return structPtr;
}
+
+
+/*
+ * Add two Size values, checking for overflow
+ */
+Size
+add_size(Size s1, Size s2)
+{
+ Size result;
+
+ result = s1 + s2;
+ /* We are assuming Size is an unsigned type here... */
+ if (result < s1 || result < s2)
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("requested shared memory size overflows size_t")));
+ return result;
+}
+
+/*
+ * Multiply two Size values, checking for overflow
+ */
+Size
+mul_size(Size s1, Size s2)
+{
+ Size result;
+
+ if (s1 == 0 || s2 == 0)
+ return 0;
+ result = s1 * s2;
+ /* We are assuming Size is an unsigned type here... */
+ if (result / s2 != s1)
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("requested shared memory size overflows size_t")));
+ return result;
+}
diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index e771eea196e..0d7b01f7966 100644
--- a/src/backend/storage/ipc/sinval.c
+++ b/src/backend/storage/ipc/sinval.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.76 2005/05/19 21:35:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.77 2005/08/20 23:26:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -55,10 +55,10 @@ static void ProcessCatchupEvent(void);
/* should be called only by the POSTMASTER */
/****************************************************************************/
void
-CreateSharedInvalidationState(int maxBackends)
+CreateSharedInvalidationState(void)
{
/* SInvalLock must be initialized already, during LWLock init */
- SIBufferInit(maxBackends);
+ SIBufferInit();
}
/*
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index 64a9672b308..612f437322a 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.59 2005/05/19 21:35:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.60 2005/08/20 23:26:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,14 +32,15 @@ static void SISetProcStateInvalid(SISeg *segP);
/*
* SInvalShmemSize --- return shared-memory space needed
*/
-int
-SInvalShmemSize(int maxBackends)
+Size
+SInvalShmemSize(void)
{
- /*
- * Figure space needed. Note sizeof(SISeg) includes the first
- * ProcState entry.
- */
- return sizeof(SISeg) + sizeof(ProcState) * (maxBackends - 1);
+ Size size;
+
+ size = offsetof(SISeg, procState);
+ size = add_size(size, mul_size(sizeof(ProcState), MaxBackends));
+
+ return size;
}
/*
@@ -47,16 +48,15 @@ SInvalShmemSize(int maxBackends)
* Create and initialize a new SI message buffer
*/
void
-SIBufferInit(int maxBackends)
+SIBufferInit(void)
{
- int segSize;
SISeg *segP;
int i;
bool found;
/* Allocate space in shared memory */
- segSize = SInvalShmemSize(maxBackends);
- shmInvalBuffer = segP = (SISeg *) ShmemInitStruct("shmInvalBuffer", segSize, &found);
+ shmInvalBuffer = segP = (SISeg *)
+ ShmemInitStruct("shmInvalBuffer", SInvalShmemSize(), &found);
if (found)
return;
@@ -64,13 +64,13 @@ SIBufferInit(int maxBackends)
segP->minMsgNum = 0;
segP->maxMsgNum = 0;
segP->lastBackend = 0;
- segP->maxBackends = maxBackends;
- segP->freeBackends = maxBackends;
+ segP->maxBackends = MaxBackends;
+ segP->freeBackends = MaxBackends;
/* The buffer[] array is initially all unused, so we need not fill it */
/* Mark all backends inactive */
- for (i = 0; i < maxBackends; i++)
+ for (i = 0; i < segP->maxBackends; i++)
{
segP->procState[i].nextMsgNum = -1; /* inactive */
segP->procState[i].resetState = false;