Skip to content

Commit 0021ae0

Browse files
committed
Fix Win32 problems with signals and sockets, by making the forkexec code
even uglier than it was already :-(. Also, on Windows only, use temporary shared memory segments instead of ordinary files to pass over critical variable values from postmaster to child processes. Magnus Hagander
1 parent e1bf652 commit 0021ae0

File tree

5 files changed

+615
-239
lines changed

5 files changed

+615
-239
lines changed

src/backend/main/main.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.92 2004/11/05 17:11:17 petere Exp $
16+
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.93 2004/11/17 00:14:09 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -118,9 +118,6 @@ main(int argc, char *argv[])
118118
argv[0], err);
119119
exit(1);
120120
}
121-
122-
/* Start our win32 signal implementation */
123-
pgwin32_signal_initialize();
124121
}
125122
#endif
126123

@@ -281,6 +278,16 @@ main(int argc, char *argv[])
281278
exit(SubPostmasterMain(argc, argv));
282279
#endif
283280

281+
#ifdef WIN32
282+
/*
283+
* Start our win32 signal implementation
284+
*
285+
* SubPostmasterMain() will do this for itself, but the remaining
286+
* modes need it here
287+
*/
288+
pgwin32_signal_initialize();
289+
#endif
290+
284291
/*
285292
* If the first argument is "-boot", then invoke bootstrap mode. (This
286293
* path is taken only for a standalone bootstrap process.)

src/backend/port/win32/signal.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.9 2004/11/09 13:01:25 petere Exp $
9+
* $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.10 2004/11/17 00:14:10 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -26,6 +26,7 @@ static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT];
2626
static int pg_signal_mask;
2727

2828
DLLIMPORT HANDLE pgwin32_signal_event;
29+
HANDLE pgwin32_initial_signal_pipe = INVALID_HANDLE_VALUE;
2930

3031

3132
/* Signal handling thread function */
@@ -154,6 +155,28 @@ pqsignal(int signum, pqsigfunc handler)
154155
return prevfunc;
155156
}
156157

158+
/* Create the signal listener pipe for specified pid */
159+
HANDLE
160+
pgwin32_create_signal_listener(pid_t pid)
161+
{
162+
char pipename[128];
163+
HANDLE pipe;
164+
165+
wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%d", (int) pid);
166+
167+
pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,
168+
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
169+
PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
170+
171+
if (pipe == INVALID_HANDLE_VALUE)
172+
ereport(ERROR,
173+
(errmsg("could not create signal listener pipe for pid %d: error code %d",
174+
(int) pid, (int) GetLastError())));
175+
176+
return pipe;
177+
}
178+
179+
157180
/*
158181
* All functions below execute on the signal handler thread
159182
* and must be synchronized as such!
@@ -210,7 +233,7 @@ static DWORD WINAPI
210233
pg_signal_thread(LPVOID param)
211234
{
212235
char pipename[128];
213-
HANDLE pipe = INVALID_HANDLE_VALUE;
236+
HANDLE pipe = pgwin32_initial_signal_pipe;
214237

215238
wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%d", GetCurrentProcessId());
216239

@@ -219,14 +242,18 @@ pg_signal_thread(LPVOID param)
219242
BOOL fConnected;
220243
HANDLE hThread;
221244

222-
pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,
223-
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
224-
PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
225245
if (pipe == INVALID_HANDLE_VALUE)
226246
{
227-
write_stderr("could not create signal listener pipe: error code %d; retrying\n", (int) GetLastError());
228-
SleepEx(500, FALSE);
229-
continue;
247+
pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,
248+
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
249+
PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
250+
251+
if (pipe == INVALID_HANDLE_VALUE)
252+
{
253+
write_stderr("could not create signal listener pipe: error code %d; retrying\n", (int) GetLastError());
254+
SleepEx(500, FALSE);
255+
continue;
256+
}
230257
}
231258

232259
fConnected = ConnectNamedPipe(pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
@@ -244,6 +271,9 @@ pg_signal_thread(LPVOID param)
244271
else
245272
/* Connection failed. Cleanup and try again */
246273
CloseHandle(pipe);
274+
275+
/* Set up so we create a new pipe on next loop */
276+
pipe = INVALID_HANDLE_VALUE;
247277
}
248278
return 0;
249279
}

src/backend/postmaster/pgstat.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* Copyright (c) 2001-2004, PostgreSQL Global Development Group
1515
*
16-
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.84 2004/10/28 01:38:41 neilc Exp $
16+
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.85 2004/11/17 00:14:12 tgl Exp $
1717
* ----------
1818
*/
1919
#include "postgres.h"
@@ -110,8 +110,9 @@ bool pgstat_collect_blocklevel = false;
110110
* ----------
111111
*/
112112
NON_EXEC_STATIC int pgStatSock = -1;
113-
static int pgStatPipe[2];
113+
NON_EXEC_STATIC int pgStatPipe[2] = {-1,-1};
114114
static struct sockaddr_storage pgStatAddr;
115+
static pid_t pgStatCollectorPid = 0;
115116

116117
static time_t last_pgstat_start_time;
117118

@@ -492,10 +493,6 @@ pgstat_forkexec(STATS_PROCESS_TYPE procType)
492493
/* postgres_exec_path is not passed by write_backend_variables */
493494
av[ac++] = postgres_exec_path;
494495

495-
/* Pipe file ids (those not passed by write_backend_variables) */
496-
snprintf(pgstatBuf[bufc++], 32, "%d", pgStatPipe[0]);
497-
snprintf(pgstatBuf[bufc++], 32, "%d", pgStatPipe[1]);
498-
499496
/* Add to the arg list */
500497
Assert(bufc <= lengthof(pgstatBuf));
501498
for (i = 0; i < bufc; i++)
@@ -517,12 +514,10 @@ pgstat_forkexec(STATS_PROCESS_TYPE procType)
517514
static void
518515
pgstat_parseArgs(int argc, char *argv[])
519516
{
520-
Assert(argc == 6);
517+
Assert(argc == 4);
521518

522519
argc = 3;
523520
StrNCpy(postgres_exec_path, argv[argc++], MAXPGPATH);
524-
pgStatPipe[0] = atoi(argv[argc++]);
525-
pgStatPipe[1] = atoi(argv[argc++]);
526521
}
527522
#endif /* EXEC_BACKEND */
528523

@@ -1385,12 +1380,13 @@ PgstatBufferMain(int argc, char *argv[])
13851380
(errcode_for_socket_access(),
13861381
errmsg("could not create pipe for statistics buffer: %m")));
13871382

1388-
#ifdef EXEC_BACKEND
13891383
/* child becomes collector process */
1390-
switch (pgstat_forkexec(STAT_PROC_COLLECTOR))
1384+
#ifdef EXEC_BACKEND
1385+
pgStatCollectorPid = pgstat_forkexec(STAT_PROC_COLLECTOR);
13911386
#else
1392-
switch (fork())
1387+
pgStatCollectorPid = fork();
13931388
#endif
1389+
switch (pgStatCollectorPid)
13941390
{
13951391
case -1:
13961392
ereport(ERROR,
@@ -1445,7 +1441,12 @@ PgstatCollectorMain(int argc, char *argv[])
14451441
pqsignal(SIGHUP, SIG_IGN);
14461442
pqsignal(SIGINT, SIG_IGN);
14471443
pqsignal(SIGTERM, SIG_IGN);
1444+
#ifndef WIN32
14481445
pqsignal(SIGQUIT, SIG_IGN);
1446+
#else
1447+
/* kluge to allow buffer process to kill collector; FIXME */
1448+
pqsignal(SIGQUIT, pgstat_exit);
1449+
#endif
14491450
pqsignal(SIGALRM, SIG_IGN);
14501451
pqsignal(SIGPIPE, SIG_IGN);
14511452
pqsignal(SIGUSR1, SIG_IGN);
@@ -1943,6 +1944,16 @@ pgstat_exit(SIGNAL_ARGS)
19431944
* be cleaner to allow any pending messages to be sent, but that
19441945
* creates a tradeoff against speed of exit.
19451946
*/
1947+
1948+
/*
1949+
* If running in bufferer, kill our collector as well. On some broken
1950+
* win32 systems, it does not shut down automatically because of issues
1951+
* with socket inheritance. XXX so why not fix the socket inheritance...
1952+
*/
1953+
#ifdef WIN32
1954+
if (pgStatCollectorPid > 0)
1955+
kill(pgStatCollectorPid, SIGQUIT);
1956+
#endif
19461957
exit(0);
19471958
}
19481959

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy