1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Add WaitForLockers in lmgr, refactoring index.c code

This is in support of a future REINDEX CONCURRENTLY feature.

Michael Paquier
This commit is contained in:
Alvaro Herrera
2013-09-27 11:46:33 -03:00
parent dddc91ddd3
commit 15732b34e8
4 changed files with 81 additions and 50 deletions

View File

@@ -533,6 +533,73 @@ ConditionalXactLockTableWait(TransactionId xid)
return true;
}
/*
* WaitForLockersMultiple
* Wait until no transaction holds locks that conflict with the given
* locktags at the given lockmode.
*
* To do this, obtain the current list of lockers, and wait on their VXIDs
* until they are finished.
*
* Note we don't try to acquire the locks on the given locktags, only the VXIDs
* of its lock holders; if somebody grabs a conflicting lock on the objects
* after we obtained our initial list of lockers, we will not wait for them.
*/
void
WaitForLockersMultiple(List *locktags, LOCKMODE lockmode)
{
List *holders = NIL;
ListCell *lc;
/* Done if no locks to wait for */
if (list_length(locktags) == 0)
return;
/* Collect the transactions we need to wait on */
foreach(lc, locktags)
{
LOCKTAG *locktag = lfirst(lc);
holders = lappend(holders, GetLockConflicts(locktag, lockmode));
}
/*
* Note: GetLockConflicts() never reports our own xid, hence we need not
* check for that. Also, prepared xacts are not reported, which is fine
* since they certainly aren't going to do anything anymore.
*/
/* Finally wait for each such transaction to complete */
foreach(lc, holders)
{
VirtualTransactionId *lockholders = lfirst(lc);
while (VirtualTransactionIdIsValid(*lockholders))
{
VirtualXactLock(*lockholders, true);
lockholders++;
}
}
list_free_deep(holders);
}
/*
* WaitForLockers
*
* Same as WaitForLockersMultiple, for a single lock tag.
*/
void
WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode)
{
List *l;
l = list_make1(&heaplocktag);
WaitForLockersMultiple(l, lockmode);
list_free(l);
}
/*
* LockDatabaseObject
*