diff options
author | Tom Lane | 2003-02-18 02:53:29 +0000 |
---|---|---|
committer | Tom Lane | 2003-02-18 02:53:29 +0000 |
commit | f690acf1044b823edbe85a67f5503a4c111bff2e (patch) | |
tree | 394df452d1ff39e89eab9f5e8edf1a802f6f33ef | |
parent | bb402a0eca39508002fe6a91c03de68f1362a509 (diff) |
Async_NotifyHandler must save and restore ImmediateInterruptOK. Fixes
known problem with failure to respond to 'pg_ctl stop -m fast', and
probable problems if SIGINT or SIGTERM arrives while processing a
SIGUSR2 interrupt that arrived while waiting for a new client query.
-rw-r--r-- | src/backend/commands/async.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index a3c27b8f81..169c4ce278 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.91 2002/09/16 01:24:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.92 2003/02/18 02:53:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -599,6 +599,16 @@ Async_NotifyHandler(SIGNAL_ARGS) if (notifyInterruptEnabled) { + bool save_ImmediateInterruptOK = ImmediateInterruptOK; + + /* + * We may be called while ImmediateInterruptOK is true; turn it off + * while messing with the NOTIFY state. (We would have to save + * and restore it anyway, because PGSemaphore operations inside + * ProcessIncomingNotify() might reset it.) + */ + ImmediateInterruptOK = false; + /* * I'm not sure whether some flavors of Unix might allow another * SIGUSR2 occurrence to recursively interrupt this routine. To @@ -626,6 +636,13 @@ Async_NotifyHandler(SIGNAL_ARGS) elog(LOG, "Async_NotifyHandler: done"); } } + + /* + * Restore ImmediateInterruptOK, and check for interrupts if needed. + */ + ImmediateInterruptOK = save_ImmediateInterruptOK; + if (save_ImmediateInterruptOK) + CHECK_FOR_INTERRUPTS(); } else { |