From a60c9e33e96a8f3694d94143d65ec6ee1fb3414b Mon Sep 17 00:00:00 2001
From: Hiroshi Inoue <inoue@tpf.co.jp>
Date: Mon, 21 Feb 2000 02:42:37 +0000
Subject: [PATCH] fix the TODO * Allow PQrequestCancel() to terminate when in
 waiting-for-lock state Changes are limited to BACKEND,however.

---
 src/backend/storage/lmgr/proc.c | 45 +++++++++++++++++++++++++--------
 src/backend/tcop/postgres.c     | 15 +++++++++--
 src/include/miscadmin.h         |  3 ++-
 3 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 01097fcd2fe..dafab7ebfd3 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.67 2000/01/26 05:57:02 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.68 2000/02/21 02:42:36 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,7 +47,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.67 2000/01/26 05:57:02 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.68 2000/02/21 02:42:36 inoue Exp $
  */
 #include <sys/time.h>
 #include <unistd.h>
@@ -312,6 +312,34 @@ InitProcess(IPCKey key)
 	on_shmem_exit(ProcKill, (caddr_t) MyProcPid);
 }
 
+/* -----------------------
+ * get off the wait queue
+ * -----------------------
+ */
+static void
+GetOffWaitqueue(PROC *proc)
+{
+	LockLockTable();
+	if (proc->links.next != INVALID_OFFSET)
+	{
+		int	lockmode = proc->token;
+		Assert(proc->waitLock->waitProcs.size > 0);
+		SHMQueueDelete(&(proc->links));
+		--proc->waitLock->waitProcs.size;
+		Assert(proc->waitLock->nHolding > 0);
+		Assert(proc->waitLock->nHolding > proc->waitLock->nActive);
+		--proc->waitLock->nHolding;
+		Assert(proc->waitLock->holders[lockmode] > 0);
+		--proc->waitLock->holders[lockmode];
+		if (proc->waitLock->activeHolders[lockmode] ==
+			proc->waitLock->holders[lockmode])
+			proc->waitLock->waitMask &= ~(1 << lockmode);
+	}
+	SHMQueueElemInit(&(proc->links));
+	UnlockLockTable();
+
+	return;
+}
 /*
  * ProcReleaseLocks() -- release all locks associated with this process
  *
@@ -322,6 +350,7 @@ ProcReleaseLocks()
 	if (!MyProc)
 		return;
 	LockReleaseAll(1, &MyProc->lockQueue);
+	GetOffWaitqueue(MyProc);
 }
 
 /*
@@ -405,15 +434,7 @@ ProcKill(int exitStatus, int pid)
 	 * get off the wait queue
 	 * ----------------
 	 */
-	LockLockTable();
-	if (proc->links.next != INVALID_OFFSET)
-	{
-		Assert(proc->waitLock->waitProcs.size > 0);
-		SHMQueueDelete(&(proc->links));
-		--proc->waitLock->waitProcs.size;
-	}
-	SHMQueueElemInit(&(proc->links));
-	UnlockLockTable();
+	GetOffWaitqueue(proc);
 
 	return;
 }
@@ -569,6 +590,7 @@ ins:;
 	timeval.it_value.tv_sec = \
 		(DeadlockCheckTimer ? DeadlockCheckTimer : DEADLOCK_CHECK_TIMER);
 
+	SetLockWaiting(true);
 	do
 	{
 		MyProc->errType = NO_ERROR;		/* reset flag after deadlock check */
@@ -588,6 +610,7 @@ ins:;
 						 IpcExclusiveLock);
 	} while (MyProc->errType == STATUS_NOT_FOUND);		/* sleep after deadlock
 														 * check */
+	SetLockWaiting(false);
 
 	/* ---------------
 	 * We were awoken before a timeout - now disable the timer
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 1f333f46af0..71087295313 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.144 2000/02/20 04:26:35 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.145 2000/02/21 02:42:35 inoue Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -810,11 +810,21 @@ FloatExceptionHandler(SIGNAL_ARGS)
 }
 
 
+static bool	lockWaiting = false;
+void SetLockWaiting(bool waiting)
+{
+	lockWaiting = waiting;
+}
 /* signal handler for query cancel signal from postmaster */
 static void
 QueryCancelHandler(SIGNAL_ARGS)
 {
 	QueryCancel = true;
+	if (lockWaiting)
+	{
+		lockWaiting = false;
+		elog(ERROR, "Query Cancel requested while waiting lock");
+	}
 }
 
 void
@@ -1503,7 +1513,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
 	if (!IsUnderPostmaster)
 	{
 		puts("\nPOSTGRES backend interactive interface ");
-		puts("$Revision: 1.144 $ $Date: 2000/02/20 04:26:35 $\n");
+		puts("$Revision: 1.145 $ $Date: 2000/02/21 02:42:35 $\n");
 	}
 
 	/*
@@ -1573,6 +1583,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
 		firstchar = ReadCommand(parser_input);
 
 		QueryCancel = false;	/* forget any earlier CANCEL signal */
+		lockWaiting = false;
 
 		/* ----------------
 		 *	 (4) disable async.c's signal handler.
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index df3de38611b..c80e7608333 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: miscadmin.h,v 1.51 2000/02/18 09:29:06 inoue Exp $
+ * $Id: miscadmin.h,v 1.52 2000/02/21 02:42:37 inoue Exp $
  *
  * NOTES
  *	  some of the information in this file will be moved to
@@ -214,6 +214,7 @@ extern ProcessingMode Mode;
 extern void IgnoreSystemIndexes(bool mode);
 extern bool IsIgnoringSystemIndexes(void);
 extern bool IsCacheInitialized(void);
+extern void SetLockWaiting(bool);
 
 /* 
  * "postmaster.pid" is a file containing postmaster's pid, being
-- 
GitLab