66 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
77 *
88 * IDENTIFICATION
9- * $PostgreSQL: pgsql/src/backend/port/win32_shmem.c,v 1.8 2009/05/04 08:36:40 mha Exp $
9+ * $PostgreSQL: pgsql/src/backend/port/win32_shmem.c,v 1.9 2009/05/05 09:48:51 mha Exp $
1010 *
1111 *-------------------------------------------------------------------------
1212 */
@@ -123,6 +123,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
123123HANDLE hmap ,
124124hmap2 ;
125125char * szShareMem ;
126+ int i ;
126127
127128/* Room for a header? */
128129Assert (size > MAXALIGN (sizeof (PGShmemHeader )));
@@ -131,54 +132,53 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
131132
132133UsedShmemSegAddr = NULL ;
133134
134- /* In case CreateFileMapping() doesn't set the error code to 0 on success */
135- SetLastError (0 );
136-
137- hmap = CreateFileMapping ((HANDLE )0xFFFFFFFF ,/* Use the pagefile */
138- NULL ,/* Default security attrs */
139- PAGE_READWRITE ,/* Memory is Read/Write */
140- 0L ,/* Size Upper 32 Bits*/
141- (DWORD )size ,/* Size Lower 32 bits */
142- szShareMem );
143-
144- if (!hmap )
145- ereport (FATAL ,
146- (errmsg ("could not create shared memory segment: %lu" ,GetLastError ()),
147- errdetail ("Failed system call was CreateFileMapping(size=%lu, name=%s)." ,
148- (unsigned long )size ,szShareMem )));
149-
150135/*
151- * If the segment already existed, CreateFileMapping() will return a
152- * handle to the existing one.
136+ * When recycling a shared memory segment, it may take a short while
137+ * before it gets dropped from the global namespace. So re-try after
138+ * sleeping for a second, and continue retrying 10 times.
139+ * (both the 1 second time and the 10 retries are completely arbitrary)
153140 */
154- if ( GetLastError () == ERROR_ALREADY_EXISTS )
141+ for ( i = 0 ; i < 10 ; i ++ )
155142{
156- /*
157- * When recycling a shared memory segment, it may take a short while
158- * before it gets dropped from the global namespace. So re-try after
159- * sleeping for a second.
160- */
161- CloseHandle (hmap );/* Close the old handle, since we got a valid
162- * one to the previous segment. */
163-
164- Sleep (1000 );
165-
166143/* In case CreateFileMapping() doesn't set the error code to 0 on success */
167144SetLastError (0 );
168145
169- hmap = CreateFileMapping ((HANDLE )0xFFFFFFFF ,NULL ,PAGE_READWRITE ,0L , (DWORD )size ,szShareMem );
146+ hmap = CreateFileMapping ((HANDLE )0xFFFFFFFF ,/* Use the pagefile */
147+ NULL ,/* Default security attrs */
148+ PAGE_READWRITE ,/* Memory is Read/Write */
149+ 0L ,/* Size Upper 32 Bits*/
150+ (DWORD )size ,/* Size Lower 32 bits */
151+ szShareMem );
152+
170153if (!hmap )
171154ereport (FATAL ,
172155(errmsg ("could not create shared memory segment: %lu" ,GetLastError ()),
173156errdetail ("Failed system call was CreateFileMapping(size=%lu, name=%s)." ,
174157 (unsigned long )size ,szShareMem )));
175158
159+ /*
160+ * If the segment already existed, CreateFileMapping() will return a
161+ * handle to the existing one.
162+ */
176163if (GetLastError ()== ERROR_ALREADY_EXISTS )
177- ereport (FATAL ,
178- (errmsg ("pre-existing shared memory block is still in use" ),
179- errhint ("Check if there are any old server processes still running, and terminate them." )));
164+ {
165+ CloseHandle (hmap );/* Close the old handle, since we got a valid
166+ * one to the previous segment. */
167+ Sleep (1000 );
168+ continue ;
169+ }
170+ break ;
180171}
181172
173+ /*
174+ * If the last call in the loop still returned ERROR_ALREADY_EXISTS, this shared memory
175+ * segment exists and we assume it belongs to somebody else.
176+ */
177+ if (GetLastError ()== ERROR_ALREADY_EXISTS )
178+ ereport (FATAL ,
179+ (errmsg ("pre-existing shared memory block is still in use" ),
180+ errhint ("Check if there are any old server processes still running, and terminate them." )));
181+
182182free (szShareMem );
183183
184184/*