mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Update for deadlock detection.
This commit is contained in:
@ -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 @@
|
|||||||
* 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 @@
|
|||||||
#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)
|
|||||||
* 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 */
|
|||||||
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 */
|
|||||||
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 */
|
|||||||
} 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)
|
|||||||
* --------------------
|
* --------------------
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
HandleDeadLock()
|
HandleDeadLock(int sig)
|
||||||
{
|
{
|
||||||
LOCK *mywaitlock;
|
LOCK *mywaitlock;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user