diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index a58b355ecf270fab08834f60f385b3aef88a09dd..bc461f0f86f369314f3bc74b5fc426be1b14b586 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.93 2001/01/16 06:11:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.94 2001/01/16 20:59:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -48,7 +48,7 @@ * This is so that we can support more backends. (system-wide semaphore * sets run out pretty fast.) -ay 4/95 * - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.93 2001/01/16 06:11:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.94 2001/01/16 20:59:34 tgl Exp $ */ #include "postgres.h" @@ -353,16 +353,19 @@ RemoveFromWaitQueue(PROC *proc) /* * Cancel any pending wait for lock, when aborting a transaction. * + * Returns true if we had been waiting for a lock, else false. + * * (Normally, this would only happen if we accept a cancel/die * interrupt while waiting; but an elog(ERROR) while waiting is * within the realm of possibility, too.) */ -void +bool LockWaitCancel(void) { /* Nothing to do if we weren't waiting for a lock */ if (!waitingForLock) - return; + return false; + waitingForLock = false; /* Turn off the deadlock timer, if it's still running (see ProcSleep) */ @@ -395,6 +398,12 @@ LockWaitCancel(void) * prematurely. */ ZeroProcSemaphore(MyProc); + + /* + * Return true even if we were kicked off the lock before we were + * able to remove ourselves. + */ + return true; } diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index ff2c0c283d28b6276a48c2c752fc6dc6d097b0e5..80a1032e9a99916a8042b1f69c6034c1461d3430 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.201 2001/01/14 05:08:16 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.202 2001/01/16 20:59:34 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -940,11 +940,14 @@ die(SIGNAL_ARGS) InterruptPending = true; ProcDiePending = true; /* - * If we're waiting for input, service the interrupt immediately + * If it's safe to interrupt, and we're waiting for input or a lock, + * service the interrupt immediately */ if (ImmediateInterruptOK && CritSectionCount == 0) { DisableNotifyInterrupt(); + /* Make sure HandleDeadLock won't run while shutting down... */ + LockWaitCancel(); ProcessInterrupts(); } } @@ -967,8 +970,16 @@ QueryCancelHandler(SIGNAL_ARGS) InterruptPending = true; QueryCancelPending = true; /* - * No point in raising Cancel if we are waiting for input ... + * If it's safe to interrupt, and we're waiting for a lock, + * service the interrupt immediately. No point in interrupting + * if we're waiting for input, however. */ + if (ImmediateInterruptOK && CritSectionCount == 0 && + LockWaitCancel()) + { + DisableNotifyInterrupt(); + ProcessInterrupts(); + } } errno = save_errno; @@ -1668,7 +1679,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.201 $ $Date: 2001/01/14 05:08:16 $\n"); + puts("$Revision: 1.202 $ $Date: 2001/01/16 20:59:34 $\n"); } /* diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index 1007013a9df0243d12a1451876e86f57ada64989..131c3397894f7e5a4f133b3b646041e3c692f093 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: proc.h,v 1.35 2001/01/16 06:11:34 tgl Exp $ + * $Id: proc.h,v 1.36 2001/01/16 20:59:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -140,7 +140,7 @@ extern PROC *ProcWakeup(PROC *proc, int errType); extern int ProcLockWakeup(LOCKMETHOD lockmethod, LOCK *lock); extern void ProcAddLock(SHM_QUEUE *elem); extern void ProcReleaseSpins(PROC *proc); -extern void LockWaitCancel(void); +extern bool LockWaitCancel(void); extern void HandleDeadLock(SIGNAL_ARGS); #endif /* PROC_H */