Re: windows shared memory error - Mailing list pgsql-hackers

From Magnus Hagander
Subject Re: windows shared memory error
Date
Msg-id 49FF503C.8040702@hagander.net
Whole thread Raw
In response to Re: windows shared memory error  (Andrew Dunstan <andrew@dunslane.net>)
Responses Re: windows shared memory error  (Alvaro Herrera <alvherre@commandprompt.com>)
Re: windows shared memory error  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
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);

      /*

pgsql-hackers by date:

Previous
From: Archana Sundararam
Date:
Subject: ALTER TABLE should change respective views
Next
From: Alvaro Herrera
Date:
Subject: Re: windows shared memory error