diff options
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 3d74654c827..e6428b69f43 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -3803,6 +3803,13 @@ PostgresMain(int argc, char *argv[], * 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 this function's signal mask + * (to wit, UnBlockSig) will be restored when longjmp'ing to here. This + * is essential in case we longjmp'd out of a signal handler on a platform + * where that leaves the signal blocked. It's not redundant with the + * unblock in AbortTransaction() because the latter is only called if we + * were inside a transaction. */ if (sigsetjmp(local_sigjmp_buf, 1) != 0) @@ -3823,11 +3830,17 @@ PostgresMain(int argc, char *argv[], /* * Forget any pending QueryCancel request, since we're returning to - * the idle loop anyway, and cancel any active timeout requests. + * the idle loop anyway, and cancel any active timeout requests. (In + * future we might want to allow some timeout requests to survive, but + * at minimum it'd be necessary to do reschedule_timeouts(), in case + * we got here because of a query cancel interrupting the SIGALRM + * interrupt handler.) Note in particular that we must clear the + * statement and lock timeout indicators, to prevent any future plain + * query cancels from being misreported as timeouts in case we're + * forgetting a timeout cancel. */ - QueryCancelPending = false; disable_all_timeouts(false); - QueryCancelPending = false; /* again in case timeout occurred */ + QueryCancelPending = false; /* second to avoid race condition */ /* * Turn off these interrupts too. This is only needed here and not in |