diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index 7cb477c6ed..ed485ea80f 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/port/win32_shmem.c,v 1.8 2009/05/04 08:36:40 mha Exp $ + * $PostgreSQL: pgsql/src/backend/port/win32_shmem.c,v 1.9 2009/05/05 09:48:51 mha Exp $ * *------------------------------------------------------------------------- */ @@ -123,6 +123,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) HANDLE hmap, hmap2; char *szShareMem; + int i; /* Room for a header? */ Assert(size > MAXALIGN(sizeof(PGShmemHeader))); @@ -131,54 +132,53 @@ 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. + * 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) */ - if (GetLastError() == ERROR_ALREADY_EXISTS) + for (i = 0; i < 10; i++) { - /* - * 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); + 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) - 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."))); + { + 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); /*