]> granicus.if.org Git - postgresql/commitdiff
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 0a36c61847306485dc367a0cfc8d70137cd13c20..704448b16fc00c3357c0ac75d8b6e9aeeb785df4 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.46 1998/12/29 18:36:29 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.47 1998/12/29 19:32:08 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,7 +46,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.46 1998/12/29 18:36:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.47 1998/12/29 19:32:08 momjian Exp $
  */
 #include <sys/time.h>
 #include <unistd.h>
@@ -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;