Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite47f93f

Browse files
committed
Refactor CHECK_FOR_INTERRUPTS() to add flexibility.
Split up CHECK_FOR_INTERRUPTS() to provide an additional macroINTERRUPTS_PENDING_CONDITION(), which just tests whether aninterrupt is pending without attempting to service it. This isuseful in situations where the caller knows that interrupts areblocked, and would like to find out if it's worth the troubleto unblock them.Also add INTERRUPTS_CAN_BE_PROCESSED(), which indicates whetherCHECK_FOR_INTERRUPTS() can be relied on to clear the pending interrupt.This commit doesn't actually add any uses of the new macros,but a follow-on bug fix will do so. Back-patch to all supportedbranches to provide infrastructure for that fix.Alvaro Herrera and Tom LaneDiscussion:https://postgr.es/m/20210513155351.GA7848@alvherre.pgsql
1 parent1b5617e commite47f93f

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

‎src/backend/tcop/postgres.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ ProcessClientWriteInterrupt(bool blocked)
554554
{
555555
/*
556556
* Don't mess with whereToSendOutput if ProcessInterrupts wouldn't
557-
*do anything.
557+
*service ProcDiePending.
558558
*/
559559
if (InterruptHoldoffCount==0&&CritSectionCount==0)
560560
{
@@ -3118,6 +3118,12 @@ RecoveryConflictInterrupt(ProcSignalReason reason)
31183118
* If an interrupt condition is pending, and it's safe to service it,
31193119
* then clear the flag and accept the interrupt. Called only when
31203120
* InterruptPending is true.
3121+
*
3122+
* Note: if INTERRUPTS_CAN_BE_PROCESSED() is true, then ProcessInterrupts
3123+
* is guaranteed to clear the InterruptPending flag before returning.
3124+
* (This is not the same as guaranteeing that it's still clear when we
3125+
* return; another interrupt could have arrived. But we promise that
3126+
* any pre-existing one will have been serviced.)
31213127
*/
31223128
void
31233129
ProcessInterrupts(void)
@@ -3248,7 +3254,11 @@ ProcessInterrupts(void)
32483254
{
32493255
/*
32503256
* Re-arm InterruptPending so that we process the cancel request as
3251-
* soon as we're done reading the message.
3257+
* soon as we're done reading the message. (XXX this is seriously
3258+
* ugly: it complicates INTERRUPTS_CAN_BE_PROCESSED(), and it means we
3259+
* can't use that macro directly as the initial test in this function,
3260+
* meaning that this code also creates opportunities for other bugs to
3261+
* appear.)
32523262
*/
32533263
InterruptPending= true;
32543264
}

‎src/include/miscadmin.h

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@
5757
* allowing die interrupts: HOLD_CANCEL_INTERRUPTS() and
5858
* RESUME_CANCEL_INTERRUPTS().
5959
*
60+
* Note that ProcessInterrupts() has also acquired a number of tasks that
61+
* do not necessarily cause a query-cancel-or-die response. Hence, it's
62+
* possible that it will just clear InterruptPending and return.
63+
*
64+
* INTERRUPTS_PENDING_CONDITION() can be checked to see whether an
65+
* interrupt needs to be serviced, without trying to do so immediately.
66+
* Some callers are also interested in INTERRUPTS_CAN_BE_PROCESSED(),
67+
* which tells whether ProcessInterrupts is sure to clear the interrupt.
68+
*
6069
* Special mechanisms are used to let an interrupt be accepted when we are
6170
* waiting for a lock or when we are waiting for command input (but, of
6271
* course, only if the interrupt holdoff counter is zero). See the
@@ -97,24 +106,27 @@ extern PGDLLIMPORT volatile uint32 CritSectionCount;
97106
/* in tcop/postgres.c */
98107
externvoidProcessInterrupts(void);
99108

109+
/* Test whether an interrupt is pending */
100110
#ifndefWIN32
111+
#defineINTERRUPTS_PENDING_CONDITION() \
112+
(unlikely(InterruptPending))
113+
#else
114+
#defineINTERRUPTS_PENDING_CONDITION() \
115+
(unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? pgwin32_dispatch_queued_signals() : 0, \
116+
unlikely(InterruptPending))
117+
#endif
101118

119+
/* Service interrupt, if one is pending and it's safe to service it now */
102120
#defineCHECK_FOR_INTERRUPTS() \
103121
do { \
104-
if (unlikely(InterruptPending)) \
105-
ProcessInterrupts(); \
106-
} while(0)
107-
#else/* WIN32 */
108-
109-
#defineCHECK_FOR_INTERRUPTS() \
110-
do { \
111-
if (unlikely(UNBLOCKED_SIGNAL_QUEUE())) \
112-
pgwin32_dispatch_queued_signals(); \
113-
if (unlikely(InterruptPending)) \
122+
if (INTERRUPTS_PENDING_CONDITION()) \
114123
ProcessInterrupts(); \
115124
} while(0)
116-
#endif/* WIN32 */
117125

126+
/* Is ProcessInterrupts() guaranteed to clear InterruptPending? */
127+
#defineINTERRUPTS_CAN_BE_PROCESSED() \
128+
(InterruptHoldoffCount == 0 && CritSectionCount == 0 && \
129+
QueryCancelHoldoffCount == 0)
118130

119131
#defineHOLD_INTERRUPTS() (InterruptHoldoffCount++)
120132

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp