Update for deadlock detection.
authorBruce Momjian <bruce@momjian.us>
Tue, 29 Dec 1998 19:32:08 +0000 (19:32 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 29 Dec 1998 19:32:08 +0000 (19:32 +0000)
src/backend/storage/lmgr/proc.c

index c75d5046c9235d2301489194336af069096225ab..1659bf3c2c9f560ea3ff34cd3b15f9c5a4efb255 100644 (file)
@@ -77,7 +77,7 @@
 #include "storage/proc.h"
 #include "utils/trace.h"
 
-static void HandleDeadLock(void);
+static void HandleDeadLock(int sig);
 static PROC *ProcWakeup(PROC *proc, int errType);
 
 #define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT]
@@ -154,6 +154,8 @@ InitProcess(IPCKey key)
         * Routine called if deadlock timer goes off. See ProcSleep()
         * ------------------
         */
+       pqsignal(SIGALRM, HandleDeadLock);
+
        SpinAcquire(ProcStructLock);
 
        /* attach to the free list */
@@ -447,8 +449,10 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */
                  TransactionId xid)    /* needed by user locks, see below */
 {
        int                     i;
-       bool            deadlock_checked = false;
        PROC       *proc;
+       bool            deadlock_checked = false;
+       struct itimerval timeval,
+                               dummy;
 
        /*
         * If the first entries in the waitQueue have a greater priority than
@@ -512,28 +516,27 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */
        SpinRelease(spinlock);
 
        /* --------------
-        * We set this so we can wake up after one second to check for a deadlock.
+        * We set this so we can wake up periodically and check for a deadlock.
         * If a deadlock is detected, the handler releases the processes
         * semaphore and aborts the current transaction.
+        *
+        * Need to zero out struct to set the interval and the micro seconds fields
+        * to 0.
         * --------------
         */
+       MemSet(&timeval, 0, sizeof(struct itimerval));
+       timeval.it_value.tv_sec = \
+               (DeadlockCheckTimer ? DeadlockCheckTimer : DEADLOCK_CHECK_TIMER);
 
        do
        {
                MyProc->errType = NO_ERROR;             /* reset flag after deadlock check */
 
-               if (deadlock_checked == false)
-               {
-                       if (sleep(DeadlockCheckTimer ? DeadlockCheckTimer : DEADLOCK_CHECK_TIMER)
-                               == 0 /* no signal interruption */ )
-                       {
-                               HandleDeadLock();
-                               deadlock_checked = true;
-                       }
-               }
-               else
-                       pause();
-               
+               if (!deadlock_checked)
+                       if (setitimer(ITIMER_REAL, &timeval, &dummy))
+                               elog(FATAL, "ProcSleep: Unable to set timer for process wakeup");
+               deadlock_checked = true;
+
                /* --------------
                 * if someone wakes us between SpinRelease and IpcSemaphoreLock,
                 * IpcSemaphoreLock will not block.  The wakeup is "saved" by
@@ -545,6 +548,14 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */
        } while (MyProc->errType == STATUS_NOT_FOUND);          /* sleep after deadlock
                                                                                                                 * check */
 
+       /* ---------------
+        * We were awoken before a timeout - now disable the timer
+        * ---------------
+        */
+       timeval.it_value.tv_sec = 0;
+       if (setitimer(ITIMER_REAL, &timeval, &dummy))
+               elog(FATAL, "ProcSleep: Unable to diable timer for process wakeup");
+
        /* ----------------
         * We were assumed to be in a critical section when we went
         * to sleep.
@@ -687,7 +698,7 @@ ProcAddLock(SHM_QUEUE *elem)
  * --------------------
  */
 static void
-HandleDeadLock()
+HandleDeadLock(int sig)
 {
        LOCK       *mywaitlock;