Merge branch 'master' of git.lumiera.org:/git/LUMIERA into gui
This commit is contained in:
commit
cb13f5f74c
3 changed files with 42 additions and 25 deletions
|
|
@ -89,7 +89,7 @@ class LumieraEnvironment(Environment):
|
|||
|
||||
#### temporary pre 1.0 SCons compatibility hack ####
|
||||
_ver = map(int, SCons.__version__.split('.')[:2])
|
||||
_old = (_ver[0]<1 and _ver[1]<98)
|
||||
_old = (_ver[0]<1 and _ver[1]<97)
|
||||
if _old:
|
||||
ConfigBase = SCons.SConf.SConf
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -41,22 +41,22 @@
|
|||
|
||||
namespace lib {
|
||||
|
||||
namespace { // implementation details
|
||||
namespace nifty { // implementation details
|
||||
|
||||
template<class X>
|
||||
struct NiftyHolder
|
||||
struct Holder
|
||||
{
|
||||
static uint accessed_;
|
||||
static char content_[sizeof(X)];
|
||||
|
||||
NiftyHolder()
|
||||
Holder()
|
||||
{
|
||||
if (!accessed_)
|
||||
new(content_) X();
|
||||
++accessed_;
|
||||
}
|
||||
|
||||
~NiftyHolder()
|
||||
~Holder()
|
||||
{
|
||||
--accessed_;
|
||||
if (0==accessed_)
|
||||
|
|
@ -73,12 +73,12 @@ namespace lib {
|
|||
};
|
||||
|
||||
template<class X>
|
||||
uint NiftyHolder<X>::accessed_;
|
||||
uint Holder<X>::accessed_;
|
||||
|
||||
template<class X>
|
||||
char NiftyHolder<X>::content_[sizeof(X)];
|
||||
char Holder<X>::content_[sizeof(X)];
|
||||
|
||||
} // (End) implementation details
|
||||
} // (End) nifty implementation details
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 NiftyHolder<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 NiftyHolder<Monitor>::accessed_; }
|
||||
uint use_count() { return nifty::Holder<PerClassMonitor>::accessed_; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Reference in a new issue