*** postgresql-7.1.3/src/backend/storage/lmgr/proc.c.orig Thu Mar 22 15:16:17 2001 --- postgresql-7.1.3/src/backend/storage/lmgr/proc.c Fri Sep 14 11:31:05 2001 *************** *** 516,531 **** SPINLOCK spinlock = lockctl->masterLock; PROC_QUEUE *waitQueue = &(lock->waitProcs); int myHeldLocks = MyProc->heldLocks; PROC *proc; int i; - #ifndef __BEOS__ struct itimerval timeval, dummy; - #else bigtime_t time_interval; - #endif /* --- 516,529 ---- SPINLOCK spinlock = lockctl->masterLock; PROC_QUEUE *waitQueue = &(lock->waitProcs); int myHeldLocks = MyProc->heldLocks; + bool early_deadlock = false; PROC *proc; int i; #ifndef __BEOS__ struct itimerval timeval, dummy; #else bigtime_t time_interval; #endif /* *************** *** 545,551 **** * immediately. This is the same as the test for immediate grant in * LockAcquire, except we are only considering the part of the wait * queue before my insertion point. - * */ if (myHeldLocks != 0) { --- 543,548 ---- *************** *** 560,568 **** /* Must I wait for him ? */ if (lockctl->conflictTab[lockmode] & proc->heldLocks) { ! /* Yes, can report deadlock failure immediately */ ! MyProc->errType = STATUS_ERROR; ! return STATUS_ERROR; } /* I must go before this waiter. Check special case. */ if ((lockctl->conflictTab[lockmode] & aheadRequests) == 0 && --- 557,570 ---- /* Must I wait for him ? */ if (lockctl->conflictTab[lockmode] & proc->heldLocks) { ! /* ! * Yes, so we have a deadlock. Easiest way to clean up ! * correctly is to call RemoveFromWaitQueue(), but we ! * can't do that until we are *on* the wait queue. ! * So, set a flag to check below, and break out of loop. ! */ ! early_deadlock = true; ! break; } /* I must go before this waiter. Check special case. */ if ((lockctl->conflictTab[lockmode] & aheadRequests) == 0 && *************** *** 610,616 **** MyProc->waitHolder = holder; MyProc->waitLockMode = lockmode; ! MyProc->errType = STATUS_OK;/* initialize result for success */ /* mark that we are waiting for a lock */ waitingForLock = true; --- 612,630 ---- MyProc->waitHolder = holder; MyProc->waitLockMode = lockmode; ! MyProc->errType = STATUS_OK; /* initialize result for success */ ! ! /* ! * If we detected deadlock, give up without waiting. This must agree ! * with HandleDeadLock's recovery code, except that we shouldn't release ! * the semaphore since we haven't tried to lock it yet. ! */ ! if (early_deadlock) ! { ! RemoveFromWaitQueue(MyProc); ! MyProc->errType = STATUS_ERROR; ! return STATUS_ERROR; ! } /* mark that we are waiting for a lock */ waitingForLock = true;