summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Korotkov2024-03-15 12:31:25 +0000
committerAlexander Korotkov2024-03-15 12:38:22 +0000
commit4c2eda67f55a8a263820d12aaeaa7e1dfe7406ee (patch)
tree165e17284c4921a2472108d9b565b859ae263d11
parenta3f349c612923b53bd168b1dfb541a4ec712b421 (diff)
Fix race condition in transaction timeout TAP tests
The interruption handler within the injection point can get stuck in an infinite loop while handling transaction timeout. To avoid this situation we reset the timeout flag before invoking the injection point. Author: Alexander Korotkov Reviewed-by: Andrey Borodin Discussion: https://postgr.es/m/ZfPchPC6oNN71X2J%40paquier.xyz
-rw-r--r--src/backend/tcop/postgres.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 7ac623019bc..fd4199a0983 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3409,8 +3409,10 @@ ProcessInterrupts(void)
/*
* If the GUC has been reset to zero, ignore the signal. This is
* important because the GUC update itself won't disable any pending
- * interrupt.
+ * interrupt. We need to unset the flag before the injection point,
+ * otherwise we could loop in interrupts checking.
*/
+ IdleInTransactionSessionTimeoutPending = false;
if (IdleInTransactionSessionTimeout > 0)
{
INJECTION_POINT("idle-in-transaction-session-timeout");
@@ -3418,13 +3420,12 @@ ProcessInterrupts(void)
(errcode(ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT),
errmsg("terminating connection due to idle-in-transaction timeout")));
}
- else
- IdleInTransactionSessionTimeoutPending = false;
}
if (TransactionTimeoutPending)
{
/* As above, ignore the signal if the GUC has been reset to zero. */
+ TransactionTimeoutPending = false;
if (TransactionTimeout > 0)
{
INJECTION_POINT("transaction-timeout");
@@ -3432,13 +3433,12 @@ ProcessInterrupts(void)
(errcode(ERRCODE_TRANSACTION_TIMEOUT),
errmsg("terminating connection due to transaction timeout")));
}
- else
- TransactionTimeoutPending = false;
}
if (IdleSessionTimeoutPending)
{
/* As above, ignore the signal if the GUC has been reset to zero. */
+ IdleSessionTimeoutPending = false;
if (IdleSessionTimeout > 0)
{
INJECTION_POINT("idle-session-timeout");
@@ -3446,8 +3446,6 @@ ProcessInterrupts(void)
(errcode(ERRCODE_IDLE_SESSION_TIMEOUT),
errmsg("terminating connection due to idle-session timeout")));
}
- else
- IdleSessionTimeoutPending = false;
}
/*