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

Commite8312b4

Browse files
committed
Don't let timeout interrupts happen unless ImmediateInterruptOK is set.
Serious oversight in commit16e1b7a:we should not allow an interrupt to take control away from mainline codeexcept when ImmediateInterruptOK is set. Just to be safe, let's adoptthe same save-clear-restore dance that's been used for many years inHandleCatchupInterrupt and HandleNotifyInterrupt, so that nothing badhappens if a timeout handler invokes code that tests or even manipulatesImmediateInterruptOK.Per report of "stuck spinlock" failures from Christophe Pettus, thoughmany other symptoms are possible. Diagnosis by Andres Freund.
1 parent50e5470 commite8312b4

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

‎src/backend/utils/misc/timeout.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -259,22 +259,27 @@ static void
259259
handle_sig_alarm(SIGNAL_ARGS)
260260
{
261261
intsave_errno=errno;
262+
boolsave_ImmediateInterruptOK=ImmediateInterruptOK;
262263

263264
/*
264265
* We may be executing while ImmediateInterruptOK is true (e.g., when
265266
* mainline is waiting for a lock). If SIGINT or similar arrives while
266267
* this code is running, we'd lose control and perhaps leave our data
267-
* structures in an inconsistent state. Hold off interrupts to prevent
268-
* that.
268+
* structures in an inconsistent state. Disable immediate interrupts, and
269+
* just to be real sure, bump the holdoff counter as well.(The reason
270+
* for this belt-and-suspenders-too approach is to make sure that nothing
271+
* bad happens if a timeout handler calls code that manipulates
272+
* ImmediateInterruptOK.)
269273
*
270-
* Note: it's possible for a SIGINT to interrupt handle_sig_alarmeven
271-
*beforewereach HOLD_INTERRUPTS(); the net effect would be as if the
272-
*SIGALRM eventhad been silently lost.Therefore error recovery must
273-
*include someaction that will allow any lost interrupt to be
274-
*rescheduled. Disablingsome or all timeouts is sufficient, or if
275-
*that's not appropriate,reschedule_timeouts() can be called. Also, the
276-
*signal blocking hazarddescribed below applies here too.
274+
* Note: it's possible for a SIGINT to interrupt handle_sig_alarmbefore
275+
* wemanage to do this; the net effect would be as if the SIGALRM event
276+
* had been silently lost.Therefore error recovery must include some
277+
* action that will allow any lost interrupt to be rescheduled. Disabling
278+
* some or all timeouts is sufficient, or if that's not appropriate,
279+
* reschedule_timeouts() can be called. Also, the signal blocking hazard
280+
* described below applies here too.
277281
*/
282+
ImmediateInterruptOK= false;
278283
HOLD_INTERRUPTS();
279284

280285
/*
@@ -330,9 +335,12 @@ handle_sig_alarm(SIGNAL_ARGS)
330335
}
331336

332337
/*
333-
* Re-allow query cancel, and then service any cancel request that arrived
334-
* meanwhile (this might in particular include a cancel request fired by
335-
* one of the timeout handlers).
338+
* Re-allow query cancel, and then try to service any cancel request that
339+
* arrived meanwhile (this might in particular include a cancel request
340+
* fired by one of the timeout handlers). Since we are in a signal
341+
* handler, we mustn't call ProcessInterrupts unless ImmediateInterruptOK
342+
* is set; if it isn't, the cancel will happen at the next mainline
343+
* CHECK_FOR_INTERRUPTS.
336344
*
337345
* Note: a longjmp from here is safe so far as our own data structures are
338346
* concerned; but on platforms that block a signal before calling the
@@ -341,7 +349,9 @@ handle_sig_alarm(SIGNAL_ARGS)
341349
* unblocking any blocked signals.
342350
*/
343351
RESUME_INTERRUPTS();
344-
CHECK_FOR_INTERRUPTS();
352+
ImmediateInterruptOK=save_ImmediateInterruptOK;
353+
if (save_ImmediateInterruptOK)
354+
CHECK_FOR_INTERRUPTS();
345355

346356
errno=save_errno;
347357
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp