diff options
Diffstat (limited to 'src/backend/storage/ipc')
-rw-r--r-- | src/backend/storage/ipc/ipci.c | 50 | ||||
-rw-r--r-- | src/backend/storage/ipc/pmsignal.c | 6 | ||||
-rw-r--r-- | src/backend/storage/ipc/procarray.c | 13 | ||||
-rw-r--r-- | src/backend/storage/ipc/shmem.c | 43 | ||||
-rw-r--r-- | src/backend/storage/ipc/sinval.c | 6 | ||||
-rw-r--r-- | src/backend/storage/ipc/sinvaladt.c | 30 |
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; |