Implement ScopeLock and use in libPS/libPS
New ScopeLock Class
The ScopeLock
class provides a RAII interface for obtaining a lock on a resource. It works with objects that implement the new ILockable
interface. The object to be locked for the lifetime of the ScopeLock
instance is a raw pointer. This allows the usage of ScopeLock
inside the target ILockable
object itself.
An example of usage is:
bool doStuff(std::shared_ptr<ILockable> dev)
{
ScopeLock lock(dev); // contructor will call dev.get() to get the raw pointer
if (!dev->action1())
return false;
if (!dev->action2())
return false;
return true;
}
This addresses issue #65.
New ILockable Interface
The ILockable
interface generalizes the interface for requesting exclusive access to an object via the lock
/unlock
functions. The interface documentation describes how the resource access lock should behave, but does not implement it. The rules are the same as for the current ICom
classes.
Calling lock
gives user exclusive access to the device represented by the class across multiple processes. Calling unlock
releases that access.
Multiple calls to lock
should increment a counter, which is then decremented by a call to unlock
. Only once the counter has reached 0 should the access be released.
The ICom
class now inherits from ILockable
.
Transition libCom and libPS to ScopeLock
All classes in libCom and libPS now use ScopeLock
for obtaining exclusive access to a communication object corresponding to a power supply.
Add spam_powersupply Example
The spam_powersupply
"example" can be used for testing the multi-process safety of a power supply implementation. It works by setting a random number to the output voltage level to a channel and the reading that value back out continuously. If the read value does not match the set value, then an error is printed.
The idea is to run several instances of spam_powersupply
at the same time, each one addressing a different channel of a multi-channel power supply. Thus is the reading of channel A interferes with reading of channel B, then the read value of channel B will be wrong.