fix the TODO
authorHiroshi Inoue <inoue@tpf.co.jp>
Mon, 21 Feb 2000 02:42:37 +0000 (02:42 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Mon, 21 Feb 2000 02:42:37 +0000 (02:42 +0000)
* Allow PQrequestCancel() to terminate when in waiting-for-lock state
Changes are limited to BACKEND,however.

src/backend/storage/lmgr/proc.c
src/backend/tcop/postgres.c
src/include/miscadmin.h

index 01097fcd2fe642ebada361535a2b3b6cd020fce8..dafab7ebfd38e45b771c5c4ac57ae8c94e0828bb 100644 (file)
@@ -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
index 1f333f46af0d687842c7282415bff94db9795ff9..71087295313bc78ad99c0ca3ca98c56846f64fd6 100644 (file)
@@ -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.
index df3de38611b0a340124c995380a7e6ad62986c63..c80e7608333ad6174115ca9bb11a41836d1b5b89 100644 (file)
@@ -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