Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6c03d98

Browse files
committed
Change API of ShmemAlloc() so it throws error rather than returning NULL.
A majority of callers seem to have believed that this was the API specalready, because they omitted any check for a NULL result, and hencewould crash on an out-of-shared-memory failure. The original proposalwas to just add such error checks everywhere, but that does nothing toprevent similar omissions in future. Instead, let's make ShmemAlloc()throw the error (so we can remove the caller-side checks that do exist),and introduce a new function ShmemAllocNoError() that has the previousbehavior of returning NULL, for the small number of callers that needthat and are prepared to do the right thing. This also lets us removethe rather wishy-washy behavior of printing a WARNING for out-of-shmem,which never made much sense: either the caller has a strategy fordealing with that, or it doesn't. It's not ShmemAlloc's business todecide whether a warning is appropriate.The v10 release notes will need to call this out as a significantsource-code change. It's likely that it will be a bug fix forextension callers too, but if not, they'll need to change to usingShmemAllocNoError().This is nominally a bug fix, but the odds that it's fixing any livebug are actually rather small, because in general the requestsbeing made by the unchecked callers were already accounted for indetermining the overall shmem size, so really they ought not fail.Between that and the possible impact on extensions, no back-patch.Discussion: <24843.1472563085@sss.pgh.pa.us>
1 parent6f7c0ea commit6c03d98

File tree

4 files changed

+26
-34
lines changed

4 files changed

+26
-34
lines changed

‎src/backend/storage/ipc/shmem.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,31 @@ InitShmemAllocation(void)
163163
/*
164164
* ShmemAlloc -- allocate max-aligned chunk from shared memory
165165
*
166-
*Assumes ShmemLock and ShmemSegHdr are initialized.
166+
*Throws error if request cannot be satisfied.
167167
*
168-
* Returns: real pointer to memory or NULL if we are out
169-
*of space. Has to return a real pointer in order
170-
*to be compatible with malloc().
168+
* Assumes ShmemLock and ShmemSegHdr are initialized.
171169
*/
172170
void*
173171
ShmemAlloc(Sizesize)
172+
{
173+
void*newSpace;
174+
175+
newSpace=ShmemAllocNoError(size);
176+
if (!newSpace)
177+
ereport(ERROR,
178+
(errcode(ERRCODE_OUT_OF_MEMORY),
179+
errmsg("out of shared memory (%zu bytes requested)",
180+
size)));
181+
returnnewSpace;
182+
}
183+
184+
/*
185+
* ShmemAllocNoError -- allocate max-aligned chunk from shared memory
186+
*
187+
* As ShmemAlloc, but returns NULL if out of space, rather than erroring.
188+
*/
189+
void*
190+
ShmemAllocNoError(Sizesize)
174191
{
175192
SizenewStart;
176193
SizenewFree;
@@ -206,11 +223,7 @@ ShmemAlloc(Size size)
206223

207224
SpinLockRelease(ShmemLock);
208225

209-
if (!newSpace)
210-
ereport(WARNING,
211-
(errcode(ERRCODE_OUT_OF_MEMORY),
212-
errmsg("out of shared memory")));
213-
226+
/* note this assert is okay with newSpace == NULL */
214227
Assert(newSpace== (void*)CACHELINEALIGN(newSpace));
215228

216229
returnnewSpace;
@@ -293,7 +306,7 @@ ShmemInitHash(const char *name, /* table string name for shmem index */
293306
* The shared memory allocator must be specified too.
294307
*/
295308
infoP->dsize=infoP->max_dsize=hash_select_dirsize(max_size);
296-
infoP->alloc=ShmemAlloc;
309+
infoP->alloc=ShmemAllocNoError;
297310
hash_flags |=HASH_SHARED_MEM |HASH_ALLOC |HASH_DIRSIZE;
298311

299312
/* look it up in the shmem index */
@@ -364,12 +377,6 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
364377
*/
365378
Assert(shmemseghdr->index==NULL);
366379
structPtr=ShmemAlloc(size);
367-
if (structPtr==NULL)
368-
ereport(ERROR,
369-
(errcode(ERRCODE_OUT_OF_MEMORY),
370-
errmsg("not enough shared memory for data structure"
371-
" \"%s\" (%zu bytes requested)",
372-
name,size)));
373380
shmemseghdr->index=structPtr;
374381
*foundPtr= FALSE;
375382
}
@@ -410,7 +417,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
410417
else
411418
{
412419
/* It isn't in the table yet. allocate and initialize it */
413-
structPtr=ShmemAlloc(size);
420+
structPtr=ShmemAllocNoError(size);
414421
if (structPtr==NULL)
415422
{
416423
/* out of memory; remove the failed ShmemIndex entry */

‎src/backend/storage/lmgr/predicate.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,12 +1184,6 @@ InitPredicateLocks(void)
11841184
requestSize=mul_size((Size)max_table_size,
11851185
PredXactListElementDataSize);
11861186
PredXact->element=ShmemAlloc(requestSize);
1187-
if (PredXact->element==NULL)
1188-
ereport(ERROR,
1189-
(errcode(ERRCODE_OUT_OF_MEMORY),
1190-
errmsg("not enough shared memory for elements of data structure"
1191-
" \"%s\" (%zu bytes requested)",
1192-
"PredXactList",requestSize)));
11931187
/* Add all elements to available list, clean. */
11941188
memset(PredXact->element,0,requestSize);
11951189
for (i=0;i<max_table_size;i++)
@@ -1255,12 +1249,6 @@ InitPredicateLocks(void)
12551249
requestSize=mul_size((Size)max_table_size,
12561250
RWConflictDataSize);
12571251
RWConflictPool->element=ShmemAlloc(requestSize);
1258-
if (RWConflictPool->element==NULL)
1259-
ereport(ERROR,
1260-
(errcode(ERRCODE_OUT_OF_MEMORY),
1261-
errmsg("not enough shared memory for elements of data structure"
1262-
" \"%s\" (%zu bytes requested)",
1263-
"RWConflictPool",requestSize)));
12641252
/* Add all elements to available list, clean. */
12651253
memset(RWConflictPool->element,0,requestSize);
12661254
for (i=0;i<max_table_size;i++)

‎src/backend/storage/lmgr/proc.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,10 @@ InitProcGlobal(void)
194194
* between groups.
195195
*/
196196
procs= (PGPROC*)ShmemAlloc(TotalProcs*sizeof(PGPROC));
197+
MemSet(procs,0,TotalProcs*sizeof(PGPROC));
197198
ProcGlobal->allProcs=procs;
198199
/* XXX allProcCount isn't really all of them; it excludes prepared xacts */
199200
ProcGlobal->allProcCount=MaxBackends+NUM_AUXILIARY_PROCS;
200-
if (!procs)
201-
ereport(FATAL,
202-
(errcode(ERRCODE_OUT_OF_MEMORY),
203-
errmsg("out of shared memory")));
204-
MemSet(procs,0,TotalProcs*sizeof(PGPROC));
205201

206202
/*
207203
* Also allocate a separate array of PGXACT structures. This is separate

‎src/include/storage/shmem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ typedef struct SHM_QUEUE
3535
externvoidInitShmemAccess(void*seghdr);
3636
externvoidInitShmemAllocation(void);
3737
externvoid*ShmemAlloc(Sizesize);
38+
externvoid*ShmemAllocNoError(Sizesize);
3839
externboolShmemAddrIsValid(constvoid*addr);
3940
externvoidInitShmemIndex(void);
4041
externHTAB*ShmemInitHash(constchar*name,longinit_size,longmax_size,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp