]> granicus.if.org Git - postgresql/commitdiff
Make the win32 shared memory code try 10 times instead of one if
authorMagnus Hagander <magnus@hagander.net>
Tue, 5 May 2009 09:48:51 +0000 (09:48 +0000)
committerMagnus Hagander <magnus@hagander.net>
Tue, 5 May 2009 09:48:51 +0000 (09:48 +0000)
it fails because the shared memory segment already exists. This
means it can take up to 10 seconds before it reports the error
if it *does* exist, but hopefully it will make the system capable
of restarting even when the server is under high load.

src/backend/port/win32_shmem.c

index 7cb477c6ed07319f490aaf754a6dacac61b53b96..ed485ea80f8bc7e0c803e77b9042802251204c07 100644 (file)
@@ -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);
 
        /*