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

Commit191b13a

Browse files
committed
Factor out lock cleanup code that is needed in several places in lock.c.
Also, remove the rather useless return value of LockReleaseAll. Changeresponse to detection of corruption in the shared lock tables to PANIC,since that is the only way of cleaning up fully.Originally an idea of Heikki Linnakangas, variously hacked on byAlvaro Herrera and Tom Lane.
1 parentee3b71f commit191b13a

File tree

3 files changed

+82
-140
lines changed

3 files changed

+82
-140
lines changed

‎contrib/userlock/user_locks.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,7 @@ user_write_unlock_oid(Oid oid)
7575
int
7676
user_unlock_all(void)
7777
{
78-
returnLockReleaseAll(USER_LOCKMETHOD, true);
78+
LockReleaseAll(USER_LOCKMETHOD, true);
79+
80+
return true;
7981
}

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

Lines changed: 77 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.151 2005/05/11 01:26:02 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.152 2005/05/19 23:30:18 tgl Exp $
1212
*
1313
* NOTES
1414
* Outside modules can create a lock table and acquire/release
@@ -166,6 +166,8 @@ static void LockCountMyLocks(SHMEM_OFFSET lockOffset, PGPROC *proc,
166166
int*myHolding);
167167
staticboolUnGrantLock(LOCK*lock,LOCKMODElockmode,
168168
PROCLOCK*proclock,LockMethodlockMethodTable);
169+
staticvoidCleanUpLock(LOCKMETHODIDlockmethodid,LOCK*lock,
170+
PROCLOCK*proclock,boolwakeupNeeded);
169171

170172

171173
/*
@@ -589,13 +591,12 @@ LockAcquire(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
589591
* anyone to release the lock object later.
590592
*/
591593
Assert(SHMQueueEmpty(&(lock->procLocks)));
592-
lock= (LOCK*)hash_search(LockMethodLockHash[lockmethodid],
593-
(void*)&(lock->tag),
594-
HASH_REMOVE,NULL);
594+
if (!hash_search(LockMethodLockHash[lockmethodid],
595+
(void*)&(lock->tag),
596+
HASH_REMOVE,NULL))
597+
elog(PANIC,"lock table corrupted");
595598
}
596599
LWLockRelease(masterLock);
597-
if (!lock)/* hash remove failed? */
598-
elog(WARNING,"lock table corrupted");
599600
ereport(ERROR,
600601
(errcode(ERRCODE_OUT_OF_MEMORY),
601602
errmsg("out of shared memory"),
@@ -708,11 +709,10 @@ LockAcquire(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
708709
{
709710
SHMQueueDelete(&proclock->lockLink);
710711
SHMQueueDelete(&proclock->procLink);
711-
proclock= (PROCLOCK*)hash_search(LockMethodProcLockHash[lockmethodid],
712-
(void*)&(proclock->tag),
713-
HASH_REMOVE,NULL);
714-
if (!proclock)
715-
elog(WARNING,"proclock table corrupted");
712+
if (!hash_search(LockMethodProcLockHash[lockmethodid],
713+
(void*)&(proclock->tag),
714+
HASH_REMOVE,NULL))
715+
elog(PANIC,"proclock table corrupted");
716716
}
717717
else
718718
PROCLOCK_PRINT("LockAcquire: NOWAIT",proclock);
@@ -784,10 +784,9 @@ RemoveLocalLock(LOCALLOCK *locallock)
784784

785785
pfree(locallock->lockOwners);
786786
locallock->lockOwners=NULL;
787-
locallock= (LOCALLOCK*)hash_search(LockMethodLocalHash[lockmethodid],
788-
(void*)&(locallock->tag),
789-
HASH_REMOVE,NULL);
790-
if (!locallock)
787+
if (!hash_search(LockMethodLocalHash[lockmethodid],
788+
(void*)&(locallock->tag),
789+
HASH_REMOVE,NULL))
791790
elog(WARNING,"locallock table corrupted");
792791
}
793792

@@ -993,6 +992,55 @@ UnGrantLock(LOCK *lock, LOCKMODE lockmode,
993992
returnwakeupNeeded;
994993
}
995994

995+
/*
996+
* CleanUpLock -- clean up after releasing a lock. We garbage-collect the
997+
* proclock and lock objects if possible, and call ProcLockWakeup if there
998+
* are remaining requests and the caller says it's OK. (Normally, this
999+
* should be called after UnGrantLock, and wakeupNeeded is the result from
1000+
* UnGrantLock.)
1001+
*
1002+
* The locktable's masterLock must be held at entry, and will be
1003+
* held at exit.
1004+
*/
1005+
staticvoid
1006+
CleanUpLock(LOCKMETHODIDlockmethodid,LOCK*lock,PROCLOCK*proclock,
1007+
boolwakeupNeeded)
1008+
{
1009+
/*
1010+
* If this was my last hold on this lock, delete my entry in the
1011+
* proclock table.
1012+
*/
1013+
if (proclock->holdMask==0)
1014+
{
1015+
PROCLOCK_PRINT("CleanUpLock: deleting",proclock);
1016+
SHMQueueDelete(&proclock->lockLink);
1017+
SHMQueueDelete(&proclock->procLink);
1018+
if (!hash_search(LockMethodProcLockHash[lockmethodid],
1019+
(void*)&(proclock->tag),
1020+
HASH_REMOVE,NULL))
1021+
elog(PANIC,"proclock table corrupted");
1022+
}
1023+
1024+
if (lock->nRequested==0)
1025+
{
1026+
/*
1027+
* The caller just released the last lock, so garbage-collect the
1028+
* lock object.
1029+
*/
1030+
LOCK_PRINT("CleanUpLock: deleting",lock,0);
1031+
Assert(SHMQueueEmpty(&(lock->procLocks)));
1032+
if (!hash_search(LockMethodLockHash[lockmethodid],
1033+
(void*)&(lock->tag),
1034+
HASH_REMOVE,NULL))
1035+
elog(PANIC,"lock table corrupted");
1036+
}
1037+
elseif (wakeupNeeded)
1038+
{
1039+
/* There are waiters on this lock, so wake them up. */
1040+
ProcLockWakeup(LockMethods[lockmethodid],lock);
1041+
}
1042+
}
1043+
9961044
/*
9971045
* GrantLockLocal -- update the locallock data structures to show
9981046
*the lock request has been granted.
@@ -1160,30 +1208,12 @@ RemoveFromWaitQueue(PGPROC *proc)
11601208

11611209
/*
11621210
* Delete the proclock immediately if it represents no already-held locks.
1163-
* This must happen now because if the owner of the lock decides to release
1164-
* it, and the requested/granted counts then go to zero, LockRelease
1165-
* expects there to be no remaining proclocks.
1166-
*/
1167-
if (proclock->holdMask==0)
1168-
{
1169-
PROCLOCK_PRINT("RemoveFromWaitQueue: deleting proclock",proclock);
1170-
SHMQueueDelete(&proclock->lockLink);
1171-
SHMQueueDelete(&proclock->procLink);
1172-
proclock= (PROCLOCK*)hash_search(LockMethodProcLockHash[lockmethodid],
1173-
(void*)&(proclock->tag),
1174-
HASH_REMOVE,NULL);
1175-
if (!proclock)
1176-
elog(WARNING,"proclock table corrupted");
1177-
}
1178-
1179-
/*
1180-
* There should still be some requests for the lock ... else what were
1181-
* we waiting for? Therefore no need to delete the lock object.
1211+
* (This must happen now because if the owner of the lock decides to
1212+
* release it, and the requested/granted counts then go to zero,
1213+
* LockRelease expects there to be no remaining proclocks.)
1214+
* Then see if any other waiters for the lock can be woken up now.
11821215
*/
1183-
Assert(waitLock->nRequested>0);
1184-
1185-
/* See if any other waiters for the lock can be woken up now */
1186-
ProcLockWakeup(LockMethods[lockmethodid],waitLock);
1216+
CleanUpLock(lockmethodid,waitLock,proclock, true);
11871217
}
11881218

11891219
/*
@@ -1221,10 +1251,7 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
12211251
Assert(lockmethodid<NumLockMethods);
12221252
lockMethodTable=LockMethods[lockmethodid];
12231253
if (!lockMethodTable)
1224-
{
1225-
elog(WARNING,"lockMethodTable is null in LockRelease");
1226-
return FALSE;
1227-
}
1254+
elog(ERROR,"bad lock method: %d",lockmethodid);
12281255

12291256
/*
12301257
* Find the LOCALLOCK entry for this lock and lockmode
@@ -1328,56 +1355,12 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
13281355
return FALSE;
13291356
}
13301357

1331-
wakeupNeeded=UnGrantLock(lock,lockmode,proclock,lockMethodTable);
1332-
13331358
/*
1334-
* If this was my last hold on this lock, delete my entry in the
1335-
* proclock table.
1359+
* Do the releasing. CleanUpLock will waken any now-wakable waiters.
13361360
*/
1337-
if (proclock->holdMask==0)
1338-
{
1339-
PROCLOCK_PRINT("LockRelease: deleting proclock",proclock);
1340-
SHMQueueDelete(&proclock->lockLink);
1341-
SHMQueueDelete(&proclock->procLink);
1342-
proclock= (PROCLOCK*)hash_search(LockMethodProcLockHash[lockmethodid],
1343-
(void*)&(proclock->tag),
1344-
HASH_REMOVE,NULL);
1345-
if (!proclock)
1346-
{
1347-
LWLockRelease(masterLock);
1348-
elog(WARNING,"proclock table corrupted");
1349-
RemoveLocalLock(locallock);
1350-
return FALSE;
1351-
}
1352-
}
1361+
wakeupNeeded=UnGrantLock(lock,lockmode,proclock,lockMethodTable);
13531362

1354-
if (lock->nRequested==0)
1355-
{
1356-
/*
1357-
* We've just released the last lock, so garbage-collect the lock
1358-
* object.
1359-
*/
1360-
LOCK_PRINT("LockRelease: deleting lock",lock,lockmode);
1361-
Assert(SHMQueueEmpty(&(lock->procLocks)));
1362-
lock= (LOCK*)hash_search(LockMethodLockHash[lockmethodid],
1363-
(void*)&(lock->tag),
1364-
HASH_REMOVE,NULL);
1365-
if (!lock)
1366-
{
1367-
LWLockRelease(masterLock);
1368-
elog(WARNING,"lock table corrupted");
1369-
RemoveLocalLock(locallock);
1370-
return FALSE;
1371-
}
1372-
}
1373-
else
1374-
{
1375-
/*
1376-
* Wake up waiters if needed.
1377-
*/
1378-
if (wakeupNeeded)
1379-
ProcLockWakeup(lockMethodTable,lock);
1380-
}
1363+
CleanUpLock(lockmethodid,lock,proclock,wakeupNeeded);
13811364

13821365
LWLockRelease(masterLock);
13831366

@@ -1397,7 +1380,7 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
13971380
* allxids == false: release all locks with Xid != 0
13981381
* (zero is the Xid used for "session" locks).
13991382
*/
1400-
bool
1383+
void
14011384
LockReleaseAll(LOCKMETHODIDlockmethodid,boolallxids)
14021385
{
14031386
HASH_SEQ_STATUSstatus;
@@ -1418,10 +1401,7 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allxids)
14181401
Assert(lockmethodid<NumLockMethods);
14191402
lockMethodTable=LockMethods[lockmethodid];
14201403
if (!lockMethodTable)
1421-
{
1422-
elog(WARNING,"bad lock method: %d",lockmethodid);
1423-
return FALSE;
1424-
}
1404+
elog(ERROR,"bad lock method: %d",lockmethodid);
14251405

14261406
numLockModes=lockMethodTable->numLockModes;
14271407
masterLock=lockMethodTable->masterLock;
@@ -1516,48 +1496,10 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allxids)
15161496
Assert(lock->nGranted <=lock->nRequested);
15171497
LOCK_PRINT("LockReleaseAll: updated",lock,0);
15181498

1519-
PROCLOCK_PRINT("LockReleaseAll: deleting",proclock);
1520-
1521-
/*
1522-
* Remove the proclock entry from the linked lists
1523-
*/
1524-
SHMQueueDelete(&proclock->lockLink);
1525-
SHMQueueDelete(&proclock->procLink);
1526-
1527-
/*
1528-
* remove the proclock entry from the hashtable
1529-
*/
1530-
proclock= (PROCLOCK*)hash_search(LockMethodProcLockHash[lockmethodid],
1531-
(void*)&(proclock->tag),
1532-
HASH_REMOVE,
1533-
NULL);
1534-
if (!proclock)
1535-
{
1536-
LWLockRelease(masterLock);
1537-
elog(WARNING,"proclock table corrupted");
1538-
return FALSE;
1539-
}
1499+
Assert(proclock->holdMask==0);
15401500

1541-
if (lock->nRequested==0)
1542-
{
1543-
/*
1544-
* We've just released the last lock, so garbage-collect the
1545-
* lock object.
1546-
*/
1547-
LOCK_PRINT("LockReleaseAll: deleting",lock,0);
1548-
Assert(SHMQueueEmpty(&(lock->procLocks)));
1549-
lock= (LOCK*)hash_search(LockMethodLockHash[lockmethodid],
1550-
(void*)&(lock->tag),
1551-
HASH_REMOVE,NULL);
1552-
if (!lock)
1553-
{
1554-
LWLockRelease(masterLock);
1555-
elog(WARNING,"lock table corrupted");
1556-
return FALSE;
1557-
}
1558-
}
1559-
elseif (wakeupNeeded)
1560-
ProcLockWakeup(lockMethodTable,lock);
1501+
/* CleanUpLock will wake up waiters if needed. */
1502+
CleanUpLock(lockmethodid,lock,proclock,wakeupNeeded);
15611503

15621504
next_item:
15631505
proclock=nextHolder;
@@ -1569,8 +1511,6 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allxids)
15691511
if (lockmethodid==USER_LOCKMETHOD ?Trace_userlocks :Trace_locks)
15701512
elog(LOG,"LockReleaseAll done");
15711513
#endif
1572-
1573-
return TRUE;
15741514
}
15751515

15761516
/*

‎src/include/storage/lock.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.85 2005/04/29 22:28:24 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.86 2005/05/19 23:30:18 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -361,7 +361,7 @@ extern bool LockAcquire(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
361361
TransactionIdxid,LOCKMODElockmode,booldontWait);
362362
externboolLockRelease(LOCKMETHODIDlockmethodid,LOCKTAG*locktag,
363363
TransactionIdxid,LOCKMODElockmode);
364-
externboolLockReleaseAll(LOCKMETHODIDlockmethodid,boolallxids);
364+
externvoidLockReleaseAll(LOCKMETHODIDlockmethodid,boolallxids);
365365
externvoidLockReleaseCurrentOwner(void);
366366
externvoidLockReassignCurrentOwner(void);
367367
externintLockCheckConflicts(LockMethodlockMethodTable,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp