From 5ee6d375c0756c8ba589f88740a7aa4da600b46b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 20 Jan 2009 02:38:13 +0100 Subject: [PATCH 1/3] SCons: fix the compatibility switch; the new code path should also be used for scons 0.97 --- admin/scons/LumieraEnvironment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index d8aeed54e..56fd81a81 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -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: From 801f070a7de3bad358cb0a44ea2194823e9d850a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 21 Jan 2009 12:19:02 +0100 Subject: [PATCH 2/3] Fix for broken logic of the ClassLock (showed up on Ubuntu Hardy) this was nice copy-n-paster error, of course the implementation namespace was never intended to be anonymous. --- src/lib/sync-classlock.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/sync-classlock.hpp b/src/lib/sync-classlock.hpp index 2cb37d17a..ea2c1a75d 100644 --- a/src/lib/sync-classlock.hpp +++ b/src/lib/sync-classlock.hpp @@ -41,22 +41,22 @@ namespace lib { - namespace { // implementation details + namespace nifty { // implementation details template - 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 - uint NiftyHolder::accessed_; + uint Holder::accessed_; template - char NiftyHolder::content_[sizeof(X)]; + char Holder::content_[sizeof(X)]; - } // (End) implementation details + } // (End) nifty implementation details @@ -100,14 +100,14 @@ namespace lib { Monitor& getPerClassMonitor() { - static NiftyHolder __used_here; + static nifty::Holder __used_here; return __used_here.get(); } public: ClassLock() : Lock (getPerClassMonitor()) {} - uint use_count() { return NiftyHolder::accessed_; } + uint use_count() { return nifty::Holder::accessed_; } }; From 974e83676ace8dcb448504ea1e49176593f7b1c2 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 21 Jan 2009 13:04:28 +0100 Subject: [PATCH 3/3] Further ClassLock refactoring; added linkonce assertion check --- src/lib/sync-classlock.hpp | 18 +++++++++++++---- tests/lib/sync-classlock-test.cpp | 33 +++++++++++++++++++------------ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/lib/sync-classlock.hpp b/src/lib/sync-classlock.hpp index ea2c1a75d..f4fe93dda 100644 --- a/src/lib/sync-classlock.hpp +++ b/src/lib/sync-classlock.hpp @@ -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 + template class ClassLock : public Sync::Lock { typedef typename Sync::Lock Lock; typedef typename sync::Monitor Monitor; + struct PerClassMonitor : Monitor {}; + Monitor& getPerClassMonitor() { - static nifty::Holder __used_here; + static nifty::Holder __used_here; + ASSERT (1==use_count(), "static init broken"); + return __used_here.get(); } public: ClassLock() : Lock (getPerClassMonitor()) {} - uint use_count() { return nifty::Holder::accessed_; } + uint use_count() { return nifty::Holder::accessed_; } }; diff --git a/tests/lib/sync-classlock-test.cpp b/tests/lib/sync-classlock-test.cpp index 81ad457d1..2cfa271e5 100644 --- a/tests/lib/sync-classlock-test.cpp +++ b/tests/lib/sync-classlock-test.cpp @@ -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 ctor_lock; } - ~Probe() { ClassLock dtor_lock; } + ClassLock 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 get_class_lock; - ASSERT ( 1 == get_class_lock.use_count()); // ClassLock got created exactly once - } + ASSERT ( 1 == get_class_lock.use_count()); // embedded PerClassMonitor got created exactly once + } // and stays alive until static dtors are called.... }; - + /** Register this test class... */ LAUNCHER (SyncClasslock_test, "unit common");