6
6
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7
7
*
8
8
* IDENTIFICATION
9
- * $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.23 2010/01/02 16:57:50 momjian Exp $
9
+ * $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.24 2010/01/31 17: 16:23 mha Exp $
10
10
*
11
11
*-------------------------------------------------------------------------
12
12
*/
@@ -275,6 +275,33 @@ pg_signal_thread(LPVOID param)
275
275
fConnected = ConnectNamedPipe (pipe , NULL ) ? TRUE : (GetLastError () == ERROR_PIPE_CONNECTED );
276
276
if (fConnected )
277
277
{
278
+ HANDLE newpipe ;
279
+
280
+ /*
281
+ * We have a connected pipe. Pass this off to a separate thread that will do the actual
282
+ * processing of the pipe.
283
+ *
284
+ * We must also create a new instance of the pipe *before* we start running the new
285
+ * thread. If we don't, there is a race condition whereby the dispatch thread might
286
+ * run CloseHandle() before we have created a new instance, thereby causing a small
287
+ * window of time where we will miss incoming requests.
288
+ */
289
+ newpipe = CreateNamedPipe (pipename , PIPE_ACCESS_DUPLEX ,
290
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT ,
291
+ PIPE_UNLIMITED_INSTANCES , 16 , 16 , 1000 , NULL );
292
+ if (newpipe == INVALID_HANDLE_VALUE )
293
+ {
294
+ /*
295
+ * This really should never fail. Just retry in case it does, even though we have
296
+ * a small race window in that case. There is nothing else we can do other than
297
+ * abort the whole process which will be even worse.
298
+ */
299
+ write_stderr ("could not create signal listener pipe: error code %d; retrying\n" , (int ) GetLastError ());
300
+ /*
301
+ * Keep going so we at least dispatch this signal. Hopefully, the call will succeed
302
+ * when retried in the loop soon after.
303
+ */
304
+ }
278
305
hThread = CreateThread (NULL , 0 ,
279
306
(LPTHREAD_START_ROUTINE ) pg_signal_dispatch_thread ,
280
307
(LPVOID ) pipe , 0 , NULL );
@@ -283,13 +310,24 @@ pg_signal_thread(LPVOID param)
283
310
(int ) GetLastError ());
284
311
else
285
312
CloseHandle (hThread );
313
+
314
+ /*
315
+ * Background thread is running with our instance of the pipe. So replace our reference
316
+ * with the newly created one and loop back up for another run.
317
+ */
318
+ pipe = newpipe ;
286
319
}
287
320
else
288
- /* Connection failed. Cleanup and try again */
321
+ {
322
+ /*
323
+ * Connection failed. Cleanup and try again.
324
+ *
325
+ * This should never happen. If it does, we have a small race condition until we loop
326
+ * up and re-create the pipe.
327
+ */
289
328
CloseHandle (pipe );
290
-
291
- /* Set up so we create a new pipe on next loop */
292
- pipe = INVALID_HANDLE_VALUE ;
329
+ pipe = INVALID_HANDLE_VALUE ;
330
+ }
293
331
}
294
332
return 0 ;
295
333
}
0 commit comments