Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 2efc6dc

Browse files
committed
Add HOLD/RESUME_INTERRUPTS in HandleCatchupInterrupt/HandleNotifyInterrupt.
This prevents a possible longjmp out of the signal handler if a timeout or SIGINT occurs while something within the handler has transiently set ImmediateInterruptOK. For safety we must hold off the timeout or cancel error until we're back in mainline, or at least till we reach the end of the signal handler when ImmediateInterruptOK was true at entry. This syncs these functions with the logic now present in handle_sig_alarm. AFAICT there is no live bug here in 9.0 and up, because I don't think we currently can wait for any heavyweight lock inside these functions, and there is no other code (except read-from-client) that will turn on ImmediateInterruptOK. However, that was not true pre-9.0: in older branches ProcessIncomingNotify might block trying to lock pg_listener, and then a SIGINT could lead to undesirable control flow. It might be all right anyway given the relatively narrow code ranges in which NOTIFY interrupts are enabled, but for safety's sake I'm back-patching this.
1 parent dde6282 commit 2efc6dc

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

src/backend/commands/async.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,11 +1650,15 @@ HandleNotifyInterrupt(void)
16501650

16511651
/*
16521652
* We may be called while ImmediateInterruptOK is true; turn it off
1653-
* while messing with the NOTIFY state. (We would have to save and
1654-
* restore it anyway, because PGSemaphore operations inside
1655-
* ProcessIncomingNotify() might reset it.)
1653+
* while messing with the NOTIFY state. This prevents problems if
1654+
* SIGINT or similar arrives while we're working. Just to be real
1655+
* sure, bump the interrupt holdoff counter as well. That way, even
1656+
* if something inside ProcessIncomingNotify() transiently sets
1657+
* ImmediateInterruptOK (eg while waiting on a lock), we won't get
1658+
* interrupted until we're done with the notify interrupt.
16561659
*/
16571660
ImmediateInterruptOK = false;
1661+
HOLD_INTERRUPTS();
16581662

16591663
/*
16601664
* I'm not sure whether some flavors of Unix might allow another
@@ -1684,8 +1688,10 @@ HandleNotifyInterrupt(void)
16841688
}
16851689

16861690
/*
1687-
* Restore ImmediateInterruptOK, and check for interrupts if needed.
1691+
* Restore the holdoff level and ImmediateInterruptOK, and check for
1692+
* interrupts if needed.
16881693
*/
1694+
RESUME_INTERRUPTS();
16891695
ImmediateInterruptOK = save_ImmediateInterruptOK;
16901696
if (save_ImmediateInterruptOK)
16911697
CHECK_FOR_INTERRUPTS();

src/backend/storage/ipc/sinval.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,15 @@ HandleCatchupInterrupt(void)
180180

181181
/*
182182
* We may be called while ImmediateInterruptOK is true; turn it off
183-
* while messing with the catchup state. (We would have to save and
184-
* restore it anyway, because PGSemaphore operations inside
185-
* ProcessCatchupEvent() might reset it.)
183+
* while messing with the catchup state. This prevents problems if
184+
* SIGINT or similar arrives while we're working. Just to be real
185+
* sure, bump the interrupt holdoff counter as well. That way, even
186+
* if something inside ProcessCatchupEvent() transiently sets
187+
* ImmediateInterruptOK (eg while waiting on a lock), we won't get
188+
* interrupted until we're done with the catchup interrupt.
186189
*/
187190
ImmediateInterruptOK = false;
191+
HOLD_INTERRUPTS();
188192

189193
/*
190194
* I'm not sure whether some flavors of Unix might allow another
@@ -208,8 +212,10 @@ HandleCatchupInterrupt(void)
208212
}
209213

210214
/*
211-
* Restore ImmediateInterruptOK, and check for interrupts if needed.
215+
* Restore the holdoff level and ImmediateInterruptOK, and check for
216+
* interrupts if needed.
212217
*/
218+
RESUME_INTERRUPTS();
213219
ImmediateInterruptOK = save_ImmediateInterruptOK;
214220
if (save_ImmediateInterruptOK)
215221
CHECK_FOR_INTERRUPTS();

0 commit comments

Comments
 (0)