There is a general purpose way of locking any number of CSpaces. Any number of threads can lock multiple CSpaces at a time without any dead-lock. To ensure this it is assumed that a thread that calls LockMultipleCSpaces() must not have already locked any CSpaces.
In the literature this approach is called conservative two phase locking. Before accessing a set of CSpaces it is necessary to lock all the CSpaces up front.
In principle it should be possible to release CSpace locks while the thread runs, as soon as it knows that it will no longer need to access the CSpace again. However, to keep the interface simple we currently don't support this.
The implementation avoids dead-lock by using the addresses of the CSpace pointers to give a total ordering on the CSpaces. By always gaining locks in this order, cycles in the wait-for-graph are impossible.
void LockMultipleCSpaces(CSpace** L, ssize_t n, ECSpaceLockMode mode)
Block until all the given CSpaces are locked with the given ECSpaceLockMode. The given array of CSpaces are first sorted by CSpace address to avoid dead-lock. Only returns if all CSpaces have been successfully locked.
void UnlockMultipleCSpaces(CSpace** L, ssize_t n)
Unlock multiple PSpaces. Must be called by the same thread that called LockMultipleCSpaces(), passing the same set of CSpaces. This is a convenience function, since each CSpace can be unlocked individually in any order as long as those that are unlocked are not accessed further.
class MultipleCSpaceLock
{
public:
MultipleCSpaceLock(CSpace** L, ssize_t n, ECSpaceLockMode mode = ECSpaceLockMode::Exclusive);
~MultipleCSpaceLock();
private:
[ implementation ]
};