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:
@@ -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
|
||||
*
|
||||
|
Reference in New Issue
Block a user