Commit 6059c5a1 authored by Bruce Momjian's avatar Bruce Momjian

Update for deadlock detection.

parent 06c120e6
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -46,7 +46,7 @@
* This is so that we can support more backends. (system-wide semaphore * This is so that we can support more backends. (system-wide semaphore
* sets run out pretty fast.) -ay 4/95 * 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 <sys/time.h>
#include <unistd.h> #include <unistd.h>
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
#include "storage/proc.h" #include "storage/proc.h"
#include "utils/trace.h" #include "utils/trace.h"
static void HandleDeadLock(void); static void HandleDeadLock(int sig);
static PROC *ProcWakeup(PROC *proc, int errType); static PROC *ProcWakeup(PROC *proc, int errType);
#define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT] #define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT]
...@@ -154,6 +154,8 @@ InitProcess(IPCKey key) ...@@ -154,6 +154,8 @@ InitProcess(IPCKey key)
* Routine called if deadlock timer goes off. See ProcSleep() * Routine called if deadlock timer goes off. See ProcSleep()
* ------------------ * ------------------
*/ */
pqsignal(SIGALRM, HandleDeadLock);
SpinAcquire(ProcStructLock); SpinAcquire(ProcStructLock);
/* attach to the free list */ /* attach to the free list */
...@@ -447,8 +449,10 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */ ...@@ -447,8 +449,10 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */
TransactionId xid) /* needed by user locks, see below */ TransactionId xid) /* needed by user locks, see below */
{ {
int i; int i;
bool deadlock_checked = false;
PROC *proc; PROC *proc;
bool deadlock_checked = false;
struct itimerval timeval,
dummy;
/* /*
* If the first entries in the waitQueue have a greater priority than * If the first entries in the waitQueue have a greater priority than
...@@ -512,28 +516,27 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */ ...@@ -512,28 +516,27 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */
SpinRelease(spinlock); 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 * If a deadlock is detected, the handler releases the processes
* semaphore and aborts the current transaction. * 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 do
{ {
MyProc->errType = NO_ERROR; /* reset flag after deadlock check */ MyProc->errType = NO_ERROR; /* reset flag after deadlock check */
if (deadlock_checked == false) if (!deadlock_checked)
{ if (setitimer(ITIMER_REAL, &timeval, &dummy))
if (sleep(DeadlockCheckTimer ? DeadlockCheckTimer : DEADLOCK_CHECK_TIMER) elog(FATAL, "ProcSleep: Unable to set timer for process wakeup");
== 0 /* no signal interruption */ ) deadlock_checked = true;
{
HandleDeadLock();
deadlock_checked = true;
}
}
else
pause();
/* -------------- /* --------------
* if someone wakes us between SpinRelease and IpcSemaphoreLock, * if someone wakes us between SpinRelease and IpcSemaphoreLock,
* IpcSemaphoreLock will not block. The wakeup is "saved" by * IpcSemaphoreLock will not block. The wakeup is "saved" by
...@@ -545,6 +548,14 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */ ...@@ -545,6 +548,14 @@ ProcSleep(PROC_QUEUE *waitQueue,/* lock->waitProcs */
} while (MyProc->errType == STATUS_NOT_FOUND); /* sleep after deadlock } while (MyProc->errType == STATUS_NOT_FOUND); /* sleep after deadlock
* check */ * 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 * We were assumed to be in a critical section when we went
* to sleep. * to sleep.
...@@ -687,7 +698,7 @@ ProcAddLock(SHM_QUEUE *elem) ...@@ -687,7 +698,7 @@ ProcAddLock(SHM_QUEUE *elem)
* -------------------- * --------------------
*/ */
static void static void
HandleDeadLock() HandleDeadLock(int sig)
{ {
LOCK *mywaitlock; LOCK *mywaitlock;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment