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

Commita7e5878

Browse files
committed
Reserve the shared memory region during backend startup on Windows, so
that memory allocated by starting third party DLLs doesn't end upconflicting with it.Hopefully this solves the long-time issue with "could not reattachto shared memory" errors on Win32.Patch from Tsutomu Yamada and me, based on idea from Trevor Talbot.
1 parent5e22994 commita7e5878

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

‎src/backend/port/win32_shmem.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/port/win32_shmem.c,v 1.11 2009/06/11 14:49:00 momjian Exp $
9+
* $PostgreSQL: pgsql/src/backend/port/win32_shmem.c,v 1.12 2009/07/24 20:12:42 mha Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -18,6 +18,7 @@
1818

1919
unsigned longUsedShmemSegID=0;
2020
void*UsedShmemSegAddr=NULL;
21+
staticSizeUsedShmemSegSize=0;
2122

2223
staticvoidpgwin32_SharedMemoryDelete(intstatus,DatumshmId);
2324

@@ -233,6 +234,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
233234

234235
/* Save info for possible future use */
235236
UsedShmemSegAddr=memAddress;
237+
UsedShmemSegSize=size;
236238
UsedShmemSegID= (unsigned long)hmap2;
237239

238240
returnhdr;
@@ -257,6 +259,13 @@ PGSharedMemoryReAttach(void)
257259
Assert(UsedShmemSegAddr!=NULL);
258260
Assert(IsUnderPostmaster);
259261

262+
/*
263+
* Release memory region reservation that was made by the postmaster
264+
*/
265+
if (VirtualFree(UsedShmemSegAddr,0,MEM_RELEASE)==0)
266+
elog(FATAL,"failed to release reserved memory region (addr=%p): %lu",
267+
UsedShmemSegAddr,GetLastError());
268+
260269
hdr= (PGShmemHeader*)MapViewOfFileEx((HANDLE)UsedShmemSegID,FILE_MAP_READ |FILE_MAP_WRITE,0,0,0,UsedShmemSegAddr);
261270
if (!hdr)
262271
elog(FATAL,"could not reattach to shared memory (key=%d, addr=%p): %lu",
@@ -302,3 +311,53 @@ pgwin32_SharedMemoryDelete(int status, Datum shmId)
302311
if (!CloseHandle((HANDLE)DatumGetInt32(shmId)))
303312
elog(LOG,"could not close handle to shared memory: %lu",GetLastError());
304313
}
314+
315+
/*
316+
* pgwin32_ReserveSharedMemoryRegion(hChild)
317+
*
318+
* Reserve the memory region that will be used for shared memory in a child
319+
* process. It is called before the child process starts, to make sure the
320+
* memory is available.
321+
*
322+
* Once the child starts, DLLs loading in different order or threads getting
323+
* scheduled differently may allocate memory which can conflict with the
324+
* address space we need for our shared memory. By reserving the shared
325+
* memory region before the child starts, and freeing it only just before we
326+
* attempt to get access to the shared memory forces these allocations to
327+
* be given different address ranges that don't conflict.
328+
*
329+
* NOTE! This function executes in the postmaster, and should for this
330+
* reason not use elog(FATAL) since that would take down the postmaster.
331+
*/
332+
int
333+
pgwin32_ReserveSharedMemoryRegion(HANDLEhChild)
334+
{
335+
void*address;
336+
337+
Assert(UsedShmemSegAddr!=NULL);
338+
Assert(UsedShmemSegSize!=0);
339+
340+
address=VirtualAllocEx(hChild,UsedShmemSegAddr,UsedShmemSegSize,
341+
MEM_RESERVE,PAGE_READWRITE);
342+
if (address==NULL) {
343+
/* Don't use FATAL since we're running in the postmaster */
344+
elog(LOG,"could not reserve shared memory region (addr=%p) for child %lu: %lu",
345+
UsedShmemSegAddr,hChild,GetLastError());
346+
return false;
347+
}
348+
if (address!=UsedShmemSegAddr)
349+
{
350+
/*
351+
* Should never happen - in theory if allocation granularity causes strange
352+
* effects it could, so check just in case.
353+
*
354+
* Don't use FATAL since we're running in the postmaster.
355+
*/
356+
elog(LOG,"reserved shared memory region got incorrect address %p, expected %p",
357+
address,UsedShmemSegAddr);
358+
VirtualFreeEx(hChild,address,0,MEM_RELEASE);
359+
return false;
360+
}
361+
362+
return true;
363+
}

‎src/backend/postmaster/postmaster.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.584 2009/07/08 18:55:35 tgl Exp $
40+
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.585 2009/07/24 20:12:42 mha Exp $
4141
*
4242
* NOTES
4343
*
@@ -3635,14 +3635,33 @@ internal_forkexec(int argc, char *argv[], Port *port)
36353635
return-1;/* log made by save_backend_variables */
36363636
}
36373637

3638-
/* Drop the shared memory that is now inherited to the backend */
3638+
/* Drop theparametershared memory that is now inherited to the backend */
36393639
if (!UnmapViewOfFile(param))
36403640
elog(LOG,"could not unmap view of backend parameter file: error code %d",
36413641
(int)GetLastError());
36423642
if (!CloseHandle(paramHandle))
36433643
elog(LOG,"could not close handle to backend parameter file: error code %d",
36443644
(int)GetLastError());
36453645

3646+
/*
3647+
* Reserve the memory region used by our main shared memory segment before we
3648+
* resume the child process.
3649+
*/
3650+
if (!pgwin32_ReserveSharedMemoryRegion(pi.hProcess))
3651+
{
3652+
/*
3653+
* Failed to reserve the memory, so terminate the newly created
3654+
* process and give up.
3655+
*/
3656+
if (!TerminateProcess(pi.hProcess,255))
3657+
ereport(ERROR,
3658+
(errmsg_internal("could not terminate process that failed to reserve memory: error code %d",
3659+
(int)GetLastError())));
3660+
CloseHandle(pi.hProcess);
3661+
CloseHandle(pi.hThread);
3662+
return-1;/* logging done made by pgwin32_ReserveSharedMemoryRegion() */
3663+
}
3664+
36463665
/*
36473666
* Now that the backend variables are written out, we start the child
36483667
* thread so it can start initializing while we set up the rest of the

‎src/include/port/win32.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.88 2009/06/11 14:49:12 momjian Exp $ */
1+
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.89 2009/07/24 20:12:42 mha Exp $ */
22

33
#if defined(_MSC_VER)|| defined(__BORLANDC__)
44
#defineWIN32_ONLY_COMPILER
@@ -288,6 +288,9 @@ extern intpgwin32_is_admin(void);
288288
externintpgwin32_is_service(void);
289289
#endif
290290

291+
/* in backend/port/win32_shmem.c */
292+
externintpgwin32_ReserveSharedMemoryRegion(HANDLE);
293+
291294
/* in port/win32error.c */
292295
externvoid_dosmaperr(unsigned long);
293296

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp