aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r--src/backend/tcop/postgres.c19
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