diff options
Diffstat (limited to 'src/backend/storage')
| -rw-r--r-- | src/backend/storage/lmgr/lmgr.c | 67 | 
1 files changed, 67 insertions, 0 deletions
| diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c index 2b7a1db3eba..a978172796d 100644 --- a/src/backend/storage/lmgr/lmgr.c +++ b/src/backend/storage/lmgr/lmgr.c @@ -534,6 +534,73 @@ ConditionalXactLockTableWait(TransactionId xid)  }  /* + * 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   *   * Obtain a lock on a general object of the current database.  Don't use | 
