Skip to content

Commit 7c8d062

Browse files
committed
Merge branch 'REL9_5_STABLE' into PGPRO9_5
2 parents 7951d67 + 73f5acc commit 7c8d062

File tree

7 files changed

+439
-322
lines changed

7 files changed

+439
-322
lines changed

src/backend/tcop/postgres.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2920,6 +2920,9 @@ ProcessInterrupts(void)
29202920

29212921
if (QueryCancelPending)
29222922
{
2923+
bool lock_timeout_occurred;
2924+
bool stmt_timeout_occurred;
2925+
29232926
/*
29242927
* Don't allow query cancel interrupts while reading input from the
29252928
* client, because we might lose sync in the FE/BE protocol. (Die
@@ -2940,17 +2943,29 @@ ProcessInterrupts(void)
29402943

29412944
/*
29422945
* If LOCK_TIMEOUT and STATEMENT_TIMEOUT indicators are both set, we
2943-
* prefer to report the former; but be sure to clear both.
2946+
* need to clear both, so always fetch both.
29442947
*/
2945-
if (get_timeout_indicator(LOCK_TIMEOUT, true))
2948+
lock_timeout_occurred = get_timeout_indicator(LOCK_TIMEOUT, true);
2949+
stmt_timeout_occurred = get_timeout_indicator(STATEMENT_TIMEOUT, true);
2950+
2951+
/*
2952+
* If both were set, we want to report whichever timeout completed
2953+
* earlier; this ensures consistent behavior if the machine is slow
2954+
* enough that the second timeout triggers before we get here. A tie
2955+
* is arbitrarily broken in favor of reporting a lock timeout.
2956+
*/
2957+
if (lock_timeout_occurred && stmt_timeout_occurred &&
2958+
get_timeout_finish_time(STATEMENT_TIMEOUT) < get_timeout_finish_time(LOCK_TIMEOUT))
2959+
lock_timeout_occurred = false; /* report stmt timeout */
2960+
2961+
if (lock_timeout_occurred)
29462962
{
2947-
(void) get_timeout_indicator(STATEMENT_TIMEOUT, true);
29482963
LockErrorCleanup();
29492964
ereport(ERROR,
29502965
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
29512966
errmsg("canceling statement due to lock timeout")));
29522967
}
2953-
if (get_timeout_indicator(STATEMENT_TIMEOUT, true))
2968+
if (stmt_timeout_occurred)
29542969
{
29552970
LockErrorCleanup();
29562971
ereport(ERROR,

src/backend/utils/misc/timeout.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ typedef struct timeout_params
3434
timeout_handler_proc timeout_handler;
3535

3636
TimestampTz start_time; /* time that timeout was last activated */
37-
TimestampTz fin_time; /* if active, time it is due to fire */
37+
TimestampTz fin_time; /* time it is, or was last, due to fire */
3838
} timeout_params;
3939

4040
/*
@@ -654,3 +654,17 @@ get_timeout_start_time(TimeoutId id)
654654
{
655655
return all_timeouts[id].start_time;
656656
}
657+
658+
/*
659+
* Return the time when the timeout is, or most recently was, due to fire
660+
*
661+
* Note: will return 0 if timeout has never been activated in this process.
662+
* However, we do *not* reset the fin_time when a timeout occurs, so as
663+
* not to create a race condition if SIGALRM fires just as some code is
664+
* about to fetch the value.
665+
*/
666+
TimestampTz
667+
get_timeout_finish_time(TimeoutId id)
668+
{
669+
return all_timeouts[id].fin_time;
670+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy