* If an exception is encountered, processing resumes here.
*
* This code is a stripped down version of PostgresMain error recovery.
+ *
+ * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask
+ * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus,
+ * signals will be blocked until we complete error recovery. It might
+ * seem that this policy makes the HOLD_INTERRUPTS() call redundant, but
+ * it is not since InterruptPending might be set already.
*/
if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{
/*
* If an exception is encountered, processing resumes here.
*
- * See notes in postgres.c about the design of this coding.
+ * Unlike most auxiliary processes, we don't attempt to continue
+ * processing after an error; we just clean up and exit. The autovac
+ * launcher is responsible for spawning another worker later.
+ *
+ * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask
+ * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus,
+ * signals will be blocked until we exit. It might seem that this policy
+ * makes the HOLD_INTERRUPTS() call redundant, but it is not since
+ * InterruptPending might be set already.
*/
if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{
*/
pqsignal(SIGCHLD, SIG_DFL);
- /* We allow SIGQUIT (quickdie) at all times */
+ /* We allow SIGQUIT (SignalHandlerForCrashExit) at all times */
sigdelset(&BlockSig, SIGQUIT);
+ PG_SETMASK(&BlockSig);
/*
* We just started, assume there has been either a shutdown or
/*
* If an exception is encountered, processing resumes here.
*
- * See notes in postgres.c about the design of this coding.
+ * You might wonder why this isn't coded as an infinite loop around a
+ * PG_TRY construct. The reason is that this is the bottom of the
+ * exception stack, and so with PG_TRY there would be no exception handler
+ * in force at all during the CATCH part. By leaving the outermost setjmp
+ * always active, we have at least some chance of recovering from an error
+ * during error recovery. (If we get into an infinite loop thereby, it
+ * will soon be stopped by overflow of elog.c's internal state stack.)
+ *
+ * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask
+ * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus,
+ * signals other than SIGQUIT will be blocked until we complete error
+ * recovery. It might seem that this policy makes the HOLD_INTERRUPTS()
+ * call redundant, but it is not since InterruptPending might be set
+ * already.
*/
if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{
*/
pqsignal(SIGCHLD, SIG_DFL);
- /* We allow SIGQUIT (quickdie) at all times */
+ /* We allow SIGQUIT (SignalHandlerForCrashExit) at all times */
sigdelset(&BlockSig, SIGQUIT);
+ PG_SETMASK(&BlockSig);
/*
* Initialize so that first time-driven event happens at the correct time.
/*
* If an exception is encountered, processing resumes here.
*
- * See notes in postgres.c about the design of this coding.
+ * You might wonder why this isn't coded as an infinite loop around a
+ * PG_TRY construct. The reason is that this is the bottom of the
+ * exception stack, and so with PG_TRY there would be no exception handler
+ * in force at all during the CATCH part. By leaving the outermost setjmp
+ * always active, we have at least some chance of recovering from an error
+ * during error recovery. (If we get into an infinite loop thereby, it
+ * will soon be stopped by overflow of elog.c's internal state stack.)
+ *
+ * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask
+ * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus,
+ * signals other than SIGQUIT will be blocked until we complete error
+ * recovery. It might seem that this policy makes the HOLD_INTERRUPTS()
+ * call redundant, but it is not since InterruptPending might be set
+ * already.
*/
if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{
*/
pqsignal(SIGCHLD, SIG_DFL);
- /* We allow SIGQUIT (quickdie) at all times */
+ /* We allow SIGQUIT (SignalHandlerForCrashExit) at all times */
sigdelset(&BlockSig, SIGQUIT);
+ PG_SETMASK(&BlockSig);
/*
* Create a memory context that we will do all our work in. We do this so
/*
* If an exception is encountered, processing resumes here.
*
- * This code is heavily based on bgwriter.c, q.v.
+ * You might wonder why this isn't coded as an infinite loop around a
+ * PG_TRY construct. The reason is that this is the bottom of the
+ * exception stack, and so with PG_TRY there would be no exception handler
+ * in force at all during the CATCH part. By leaving the outermost setjmp
+ * always active, we have at least some chance of recovering from an error
+ * during error recovery. (If we get into an infinite loop thereby, it
+ * will soon be stopped by overflow of elog.c's internal state stack.)
+ *
+ * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask
+ * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus,
+ * signals other than SIGQUIT will be blocked until we complete error
+ * recovery. It might seem that this policy makes the HOLD_INTERRUPTS()
+ * call redundant, but it is not since InterruptPending might be set
+ * already.
*/
if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{
/* Reset some signals that are accepted by postmaster but not here */
pqsignal(SIGCHLD, SIG_DFL);
- /* We allow SIGQUIT (quickdie) at all times */
+ /* We allow SIGQUIT (SignalHandlerForCrashExit) at all times */
sigdelset(&BlockSig, SIGQUIT);
+ PG_SETMASK(&BlockSig);
/* Load the libpq-specific functions */
load_file("libpqwalreceiver", false);