Andrew Dunstan wrote:
>
>
> Magnus Hagander wrote:
>>
>> Andrew, you want to write up a patch or do you want me to do it?
>>
>>
>>
>
> Go for it.
How does this look?
Passes my tests, but I can't really reproduce the requirement to retry,
so I haven't been able to test that part :(
//Magnus
*** a/src/backend/port/win32_shmem.c
--- b/src/backend/port/win32_shmem.c
***************
*** 123,128 **** PGSharedMemoryCreate(Size size, bool makePrivate, int port)
--- 123,129 ----
HANDLE hmap,
hmap2;
char *szShareMem;
+ int i;
/* Room for a header? */
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
***************
*** 131,184 **** PGSharedMemoryCreate(Size size, bool makePrivate, int port)
UsedShmemSegAddr = NULL;
- /* In case CreateFileMapping() doesn't set the error code to 0 on success */
- SetLastError(0);
-
- hmap = CreateFileMapping((HANDLE) 0xFFFFFFFF, /* Use the pagefile */
- NULL, /* Default security attrs */
- PAGE_READWRITE, /* Memory is Read/Write */
- 0L, /* Size Upper 32 Bits */
- (DWORD) size, /* Size Lower 32 bits */
- szShareMem);
-
- if (!hmap)
- ereport(FATAL,
- (errmsg("could not create shared memory segment: %lu", GetLastError()),
- errdetail("Failed system call was CreateFileMapping(size=%lu, name=%s).",
- (unsigned long) size, szShareMem)));
-
/*
! * If the segment already existed, CreateFileMapping() will return a
! * handle to the existing one.
*/
! if (GetLastError() == ERROR_ALREADY_EXISTS)
{
- /*
- * When recycling a shared memory segment, it may take a short while
- * before it gets dropped from the global namespace. So re-try after
- * sleeping for a second.
- */
- CloseHandle(hmap); /* Close the old handle, since we got a valid
- * one to the previous segment. */
-
- Sleep(1000);
-
/* In case CreateFileMapping() doesn't set the error code to 0 on success */
SetLastError(0);
! hmap = CreateFileMapping((HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0L, (DWORD) size, szShareMem);
if (!hmap)
ereport(FATAL,
(errmsg("could not create shared memory segment: %lu", GetLastError()),
errdetail("Failed system call was CreateFileMapping(size=%lu, name=%s).",
(unsigned long) size, szShareMem)));
if (GetLastError() == ERROR_ALREADY_EXISTS)
! ereport(FATAL,
! (errmsg("pre-existing shared memory block is still in use"),
! errhint("Check if there are any old server processes still running, and terminate them.")));
}
free(szShareMem);
/*
--- 132,184 ----
UsedShmemSegAddr = NULL;
/*
! * When recycling a shared memory segment, it may take a short while
! * before it gets dropped from the global namespace. So re-try after
! * sleeping for a second, and continue retrying 10 times.
! * (both the 1 second time and the 10 retries are completely arbitrary)
*/
! for (i = 0; i < 10; i++)
{
/* In case CreateFileMapping() doesn't set the error code to 0 on success */
SetLastError(0);
! hmap = CreateFileMapping((HANDLE) 0xFFFFFFFF, /* Use the pagefile */
! NULL, /* Default security attrs */
! PAGE_READWRITE, /* Memory is Read/Write */
! 0L, /* Size Upper 32 Bits */
! (DWORD) size, /* Size Lower 32 bits */
! szShareMem);
!
if (!hmap)
ereport(FATAL,
(errmsg("could not create shared memory segment: %lu", GetLastError()),
errdetail("Failed system call was CreateFileMapping(size=%lu, name=%s).",
(unsigned long) size, szShareMem)));
+ /*
+ * If the segment already existed, CreateFileMapping() will return a
+ * handle to the existing one.
+ */
if (GetLastError() == ERROR_ALREADY_EXISTS)
! {
! CloseHandle(hmap); /* Close the old handle, since we got a valid
! * one to the previous segment. */
! Sleep(1000);
! continue;
! }
! break;
}
+ /*
+ * If the last call in the loop still returned ERROR_ALREADY_EXISTS, this shared memory
+ * segment exists and we assume it belongs to somebody else.
+ */
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ ereport(FATAL,
+ (errmsg("pre-existing shared memory block is still in use"),
+ errhint("Check if there are any old server processes still running, and terminate them.")));
+
free(szShareMem);
/*
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers