From: Bruce Momjian Date: Tue, 29 Dec 1998 19:32:08 +0000 (+0000) Subject: Update for deadlock detection. X-Git-Tag: REL6_5~855 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6059c5a14131cdb71750838ddd7b2034fe540193;p=postgresql Update for deadlock detection. --- diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 0a36c61847..704448b16f 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -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 #include @@ -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;