Further ClassLock refactoring; added linkonce assertion check

This commit is contained in:
Fischlurch 2009-01-21 13:04:28 +01:00
parent 801f070a7d
commit 974e83676a
2 changed files with 34 additions and 17 deletions

View file

@ -87,27 +87,37 @@ namespace lib {
* to the parameter type as a whole, not an individual instance.
* After creating an instance, every other access specifying the same
* type is blocked.
* @warn beware of recursion when using a nonrecursive Mutex
* @note the Lock is recursive, because several instances within the same
* thread may want to acquire it at the same time without deadlock.
* @note there is a design sloppiness, as two instantiations of the
* ClassLock template with differing CONF count as different type.
* Actually using two different configurations within for a single
* class X should be detected and flagged as error, but actually
* just two non-shared lock instances get created silently. Beware!
* @see Sync::Lock the usual simple instance-bound variant
*/
template<class X, class CONF = NonrecursiveLock_NoWait>
template<class X, class CONF = RecursiveLock_NoWait>
class ClassLock
: public Sync<CONF>::Lock
{
typedef typename Sync<CONF>::Lock Lock;
typedef typename sync::Monitor<CONF> Monitor;
struct PerClassMonitor : Monitor {};
Monitor&
getPerClassMonitor()
{
static nifty::Holder<Monitor> __used_here;
static nifty::Holder<PerClassMonitor> __used_here;
ASSERT (1==use_count(), "static init broken");
return __used_here.get();
}
public:
ClassLock() : Lock (getPerClassMonitor()) {}
uint use_count() { return nifty::Holder<Monitor>::accessed_; }
uint use_count() { return nifty::Holder<PerClassMonitor>::accessed_; }
};

View file

@ -34,22 +34,25 @@ using test::Test;
namespace lib {
namespace test {
namespace { // private test classes and data...
namespace { // private test classes and data...
const uint NUM_INSTANCES = 20; ///< number of probe instances to create
/**
* instances of this probe class will be created statically.
* They utilise the class-based locking within ctor and dtor
/**
* Several instances of this probe class will be created.
* Each of them acquires the shared lock; but anyway, just
* by defining this class, the embedded Monitor got created.
*/
struct Probe
{
Probe() { ClassLock<Probe> ctor_lock; }
~Probe() { ClassLock<Probe> dtor_lock; }
ClassLock<Probe> shared_lock_;
Probe() {}
~Probe() {}
};
} // (End) test classes and data....
@ -76,17 +79,21 @@ namespace lib {
{
virtual void
run (Arg)
run (Arg)
{
static Probe objs[NUM_INSTANCES];
{
Probe objs[NUM_INSTANCES];
ASSERT (1 == objs[0].shared_lock_.use_count());
}
ClassLock<Probe> get_class_lock;
ASSERT ( 1 == get_class_lock.use_count()); // ClassLock<Probe> got created exactly once
}
ASSERT ( 1 == get_class_lock.use_count()); // embedded PerClassMonitor<Probe> got created exactly once
} // and stays alive until static dtors are called....
};
/** Register this test class... */
LAUNCHER (SyncClasslock_test, "unit common");