no-sa-restart.patch
text/x-diff
Filename: no-sa-restart.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/postmaster/postmaster.c | 0 | 0 |
| src/include/port.h | 0 | 0 |
| src/port/pqsignal.c | 0 | 0 |
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index c382345..52b5e2c 100644
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
*************** PostmasterMain(int argc, char *argv[])
*** 610,615 ****
--- 610,624 ----
/*
* Set up signal handlers for the postmaster process.
*
+ * In the postmaster, we want to install non-ignored handlers *without*
+ * SA_RESTART. This is because they'll be blocked at all times except
+ * when ServerLoop is waiting for something to happen, and during that
+ * window, we want signals to exit the select(2) wait so that ServerLoop
+ * can respond if anything interesting happened. On some platforms,
+ * signals marked SA_RESTART would not cause the select() wait to end.
+ * Child processes will generally want SA_RESTART, but we expect them to
+ * set up their own handlers before unblocking signals.
+ *
* CAUTION: when changing this list, check for side-effects on the signal
* handling setup of child processes. See tcop/postgres.c,
* bootstrap/bootstrap.c, postmaster/bgwriter.c, postmaster/walwriter.c,
*************** PostmasterMain(int argc, char *argv[])
*** 620,635 ****
pqinitmask();
PG_SETMASK(&BlockSig);
! pqsignal(SIGHUP, SIGHUP_handler); /* reread config file and have
! * children do same */
! pqsignal(SIGINT, pmdie); /* send SIGTERM and shut down */
! pqsignal(SIGQUIT, pmdie); /* send SIGQUIT and die */
! pqsignal(SIGTERM, pmdie); /* wait for children and shut down */
pqsignal(SIGALRM, SIG_IGN); /* ignored */
pqsignal(SIGPIPE, SIG_IGN); /* ignored */
! pqsignal(SIGUSR1, sigusr1_handler); /* message from child process */
! pqsignal(SIGUSR2, dummy_handler); /* unused, reserve for children */
! pqsignal(SIGCHLD, reaper); /* handle child termination */
pqsignal(SIGTTIN, SIG_IGN); /* ignored */
pqsignal(SIGTTOU, SIG_IGN); /* ignored */
/* ignore SIGXFSZ, so that ulimit violations work like disk full */
--- 629,648 ----
pqinitmask();
PG_SETMASK(&BlockSig);
! pqsignal_no_restart(SIGHUP, SIGHUP_handler); /* reread config file
! * and have children do
! * same */
! pqsignal_no_restart(SIGINT, pmdie); /* send SIGTERM and shut down */
! pqsignal_no_restart(SIGQUIT, pmdie); /* send SIGQUIT and die */
! pqsignal_no_restart(SIGTERM, pmdie); /* wait for children and shut
! * down */
pqsignal(SIGALRM, SIG_IGN); /* ignored */
pqsignal(SIGPIPE, SIG_IGN); /* ignored */
! pqsignal_no_restart(SIGUSR1, sigusr1_handler); /* message from child
! * process */
! pqsignal_no_restart(SIGUSR2, dummy_handler); /* unused, reserve for
! * children */
! pqsignal_no_restart(SIGCHLD, reaper); /* handle child termination */
pqsignal(SIGTTIN, SIG_IGN); /* ignored */
pqsignal(SIGTTOU, SIG_IGN); /* ignored */
/* ignore SIGXFSZ, so that ulimit violations work like disk full */
diff --git a/src/include/port.h b/src/include/port.h
index c6937e5..52910ed 100644
*** a/src/include/port.h
--- b/src/include/port.h
*************** extern int pg_mkdir_p(char *path, int om
*** 469,474 ****
--- 469,479 ----
/* port/pqsignal.c */
typedef void (*pqsigfunc) (int signo);
extern pqsigfunc pqsignal(int signo, pqsigfunc func);
+ #ifndef WIN32
+ extern pqsigfunc pqsignal_no_restart(int signo, pqsigfunc func);
+ #else
+ #define pqsignal_no_restart(signo, func) pqsignal(signo, func)
+ #endif
/* port/quotes.c */
extern char *escape_single_quotes_ascii(const char *src);
diff --git a/src/port/pqsignal.c b/src/port/pqsignal.c
index 5d366da..e7e4451 100644
*** a/src/port/pqsignal.c
--- b/src/port/pqsignal.c
***************
*** 32,38 ****
#if !defined(WIN32) || defined(FRONTEND)
/*
! * Set up a signal handler for signal "signo"
*
* Returns the previous handler.
*/
--- 32,38 ----
#if !defined(WIN32) || defined(FRONTEND)
/*
! * Set up a signal handler, with SA_RESTART, for signal "signo"
*
* Returns the previous handler.
*/
*************** pqsignal(int signo, pqsigfunc func)
*** 58,61 ****
--- 58,90 ----
#endif
}
+ /*
+ * Set up a signal handler, without SA_RESTART, for signal "signo"
+ *
+ * Returns the previous handler.
+ *
+ * On Windows, this would be identical to pqsignal(), so don't bother.
+ */
+ #ifndef WIN32
+
+ pqsigfunc
+ pqsignal_no_restart(int signo, pqsigfunc func)
+ {
+ struct sigaction act,
+ oact;
+
+ act.sa_handler = func;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ #ifdef SA_NOCLDSTOP
+ if (signo == SIGCHLD)
+ act.sa_flags |= SA_NOCLDSTOP;
+ #endif
+ if (sigaction(signo, &act, &oact) < 0)
+ return SIG_ERR;
+ return oact.sa_handler;
+ }
+
+ #endif /* !WIN32 */
+
#endif /* !defined(WIN32) || defined(FRONTEND) */