88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.100 2001/03/22 06:16:17 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.100.2.1 2001/09/12 17:14:39 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -516,16 +516,14 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
516516SPINLOCK spinlock = lockctl -> masterLock ;
517517PROC_QUEUE * waitQueue = & (lock -> waitProcs );
518518int myHeldLocks = MyProc -> heldLocks ;
519+ bool early_deadlock = false;
519520PROC * proc ;
520521int i ;
521-
522522#ifndef __BEOS__
523523struct itimerval timeval ,
524524dummy ;
525-
526525#else
527526bigtime_t time_interval ;
528-
529527#endif
530528
531529/*
@@ -545,7 +543,6 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
545543 * immediately. This is the same as the test for immediate grant in
546544 * LockAcquire, except we are only considering the part of the wait
547545 * queue before my insertion point.
548- *
549546 */
550547if (myHeldLocks != 0 )
551548{
@@ -560,9 +557,14 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
560557/* Must I wait for him ? */
561558if (lockctl -> conflictTab [lockmode ]& proc -> heldLocks )
562559{
563- /* Yes, can report deadlock failure immediately */
564- MyProc -> errType = STATUS_ERROR ;
565- return STATUS_ERROR ;
560+ /*
561+ * Yes, so we have a deadlock. Easiest way to clean up
562+ * correctly is to call RemoveFromWaitQueue(), but we
563+ * can't do that until we are *on* the wait queue.
564+ * So, set a flag to check below, and break out of loop.
565+ */
566+ early_deadlock = true;
567+ break ;
566568}
567569/* I must go before this waiter. Check special case. */
568570if ((lockctl -> conflictTab [lockmode ]& aheadRequests )== 0 &&
@@ -610,7 +612,19 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
610612MyProc -> waitHolder = holder ;
611613MyProc -> waitLockMode = lockmode ;
612614
613- MyProc -> errType = STATUS_OK ;/* initialize result for success */
615+ MyProc -> errType = STATUS_OK ;/* initialize result for success */
616+
617+ /*
618+ * If we detected deadlock, give up without waiting. This must agree
619+ * with HandleDeadLock's recovery code, except that we shouldn't release
620+ * the semaphore since we haven't tried to lock it yet.
621+ */
622+ if (early_deadlock )
623+ {
624+ RemoveFromWaitQueue (MyProc );
625+ MyProc -> errType = STATUS_ERROR ;
626+ return STATUS_ERROR ;
627+ }
614628
615629/* mark that we are waiting for a lock */
616630waitingForLock = true;
@@ -703,6 +717,10 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
703717 *
704718 * Also remove the process from the wait queue and set its links invalid.
705719 * RETURN: the next process in the wait queue.
720+ *
721+ * XXX: presently, this code is only used for the "success" case, and only
722+ * works correctly for that case. To clean up in failure case, would need
723+ * to twiddle the lock's request counts too --- see RemoveFromWaitQueue.
706724 */
707725PROC *
708726ProcWakeup (PROC * proc ,int errType )