I wrote: > As for the question of SIGQUIT handling, I see that postgres.c > does "PG_SETMASK(&BlockSig)" immediately after applying the sigdelset > change, so there probably isn't any harm in having the background > processes do likewise.
Concretely, something about like this (I just did the bgwriter, but we'd want the same in all the background processes). I tried to respond to Robert's complaint about the inaccurate comment just above sigsetjmp, too. This passes check-world, for what little that's worth. regards, tom lane
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index 069e27e427..3ae7901bf6 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -117,6 +117,7 @@ BackgroundWriterMain(void) /* We allow SIGQUIT (quickdie) at all times */ sigdelset(&BlockSig, SIGQUIT); + PG_SETMASK(&BlockSig); /* * We just started, assume there has been either a shutdown or @@ -140,7 +141,19 @@ BackgroundWriterMain(void) /* * 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 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) {