Re: Parallel worker hangs while handling errors. - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Parallel worker hangs while handling errors.
Date
Msg-id 792142.1599168575@sss.pgh.pa.us
Whole thread Raw
In response to Re: Parallel worker hangs while handling errors.  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Parallel worker hangs while handling errors.
List pgsql-hackers
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)
     {

pgsql-hackers by date:

Previous
From: "Bossart, Nathan"
Date:
Subject: Re: Maximum password length
Next
From: Tom Lane
Date:
Subject: Re: report expected contrecord size