Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb553cba

Browse files
committed
Clean up the lock state properly when aborting because of early deadlock
detection in ProcSleep(). Bug noted by Tomasz Zielonka --- how did thisescape detection for this long??
1 parent3c59a9e commitb553cba

File tree

1 file changed

+27
-9
lines changed
  • src/backend/storage/lmgr

1 file changed

+27
-9
lines changed

‎src/backend/storage/lmgr/proc.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.104 2001/07/06 21:04:26 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.105 2001/09/04 02:26:57 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -506,16 +506,14 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
506506
SPINLOCKspinlock=lockctl->masterLock;
507507
PROC_QUEUE*waitQueue=&(lock->waitProcs);
508508
intmyHeldLocks=MyProc->heldLocks;
509+
boolearly_deadlock= false;
509510
PROC*proc;
510511
inti;
511-
512512
#ifndef__BEOS__
513513
structitimervaltimeval,
514514
dummy;
515-
516515
#else
517516
bigtime_ttime_interval;
518-
519517
#endif
520518

521519
/*
@@ -535,7 +533,6 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
535533
* immediately. This is the same as the test for immediate grant in
536534
* LockAcquire, except we are only considering the part of the wait
537535
* queue before my insertion point.
538-
*
539536
*/
540537
if (myHeldLocks!=0)
541538
{
@@ -550,9 +547,14 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
550547
/* Must I wait for him ? */
551548
if (lockctl->conflictTab[lockmode]&proc->heldLocks)
552549
{
553-
/* Yes, can report deadlock failure immediately */
554-
MyProc->errType=STATUS_ERROR;
555-
returnSTATUS_ERROR;
550+
/*
551+
* Yes, so we have a deadlock. Easiest way to clean up
552+
* correctly is to call RemoveFromWaitQueue(), but we
553+
* can't do that until we are *on* the wait queue.
554+
* So, set a flag to check below, and break out of loop.
555+
*/
556+
early_deadlock= true;
557+
break;
556558
}
557559
/* I must go before this waiter. Check special case. */
558560
if ((lockctl->conflictTab[lockmode]&aheadRequests)==0&&
@@ -600,7 +602,19 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
600602
MyProc->waitHolder=holder;
601603
MyProc->waitLockMode=lockmode;
602604

603-
MyProc->errType=STATUS_OK;/* initialize result for success */
605+
MyProc->errType=STATUS_OK;/* initialize result for success */
606+
607+
/*
608+
* If we detected deadlock, give up without waiting. This must agree
609+
* with HandleDeadLock's recovery code, except that we shouldn't release
610+
* the semaphore since we haven't tried to lock it yet.
611+
*/
612+
if (early_deadlock)
613+
{
614+
RemoveFromWaitQueue(MyProc);
615+
MyProc->errType=STATUS_ERROR;
616+
returnSTATUS_ERROR;
617+
}
604618

605619
/* mark that we are waiting for a lock */
606620
waitingForLock= true;
@@ -693,6 +707,10 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
693707
*
694708
* Also remove the process from the wait queue and set its links invalid.
695709
* RETURN: the next process in the wait queue.
710+
*
711+
* XXX: presently, this code is only used for the "success" case, and only
712+
* works correctly for that case. To clean up in failure case, would need
713+
* to twiddle the lock's request counts too --- see RemoveFromWaitQueue.
696714
*/
697715
PROC*
698716
ProcWakeup(PROC*proc,interrType)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp