Merge branch 'master' of git.lumiera.org:/git/LUMIERA into gui

This commit is contained in:
Joel Holdsworth 2009-01-21 18:21:08 +00:00
commit cb13f5f74c
3 changed files with 42 additions and 25 deletions

View file

@ -89,7 +89,7 @@ class LumieraEnvironment(Environment):
#### temporary pre 1.0 SCons compatibility hack #### #### temporary pre 1.0 SCons compatibility hack ####
_ver = map(int, SCons.__version__.split('.')[:2]) _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: if _old:
ConfigBase = SCons.SConf.SConf ConfigBase = SCons.SConf.SConf
else: else:

View file

@ -41,22 +41,22 @@
namespace lib { namespace lib {
namespace { // implementation details namespace nifty { // implementation details
template<class X> template<class X>
struct NiftyHolder struct Holder
{ {
static uint accessed_; static uint accessed_;
static char content_[sizeof(X)]; static char content_[sizeof(X)];
NiftyHolder() Holder()
{ {
if (!accessed_) if (!accessed_)
new(content_) X(); new(content_) X();
++accessed_; ++accessed_;
} }
~NiftyHolder() ~Holder()
{ {
--accessed_; --accessed_;
if (0==accessed_) if (0==accessed_)
@ -73,12 +73,12 @@ namespace lib {
}; };
template<class X> template<class X>
uint NiftyHolder<X>::accessed_; uint Holder<X>::accessed_;
template<class X> 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. * to the parameter type as a whole, not an individual instance.
* After creating an instance, every other access specifying the same * After creating an instance, every other access specifying the same
* type is blocked. * 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 * @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 class ClassLock
: public Sync<CONF>::Lock : public Sync<CONF>::Lock
{ {
typedef typename Sync<CONF>::Lock Lock; typedef typename Sync<CONF>::Lock Lock;
typedef typename sync::Monitor<CONF> Monitor; typedef typename sync::Monitor<CONF> Monitor;
struct PerClassMonitor : Monitor {};
Monitor& Monitor&
getPerClassMonitor() getPerClassMonitor()
{ {
static NiftyHolder<Monitor> __used_here; static nifty::Holder<PerClassMonitor> __used_here;
ASSERT (1==use_count(), "static init broken");
return __used_here.get(); return __used_here.get();
} }
public: public:
ClassLock() : Lock (getPerClassMonitor()) {} ClassLock() : Lock (getPerClassMonitor()) {}
uint use_count() { return NiftyHolder<Monitor>::accessed_; } uint use_count() { return nifty::Holder<PerClassMonitor>::accessed_; }
}; };

View file

@ -41,13 +41,16 @@ namespace lib {
/** /**
* instances of this probe class will be created statically. * Several instances of this probe class will be created.
* They utilise the class-based locking within ctor and dtor * Each of them acquires the shared lock; but anyway, just
* by defining this class, the embedded Monitor got created.
*/ */
struct Probe struct Probe
{ {
Probe() { ClassLock<Probe> ctor_lock; } ClassLock<Probe> shared_lock_;
~Probe() { ClassLock<Probe> dtor_lock; }
Probe() {}
~Probe() {}
}; };
@ -78,11 +81,15 @@ namespace lib {
virtual void 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; 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....
}; };