From e178bd08113646797bd8e0a6a6efd00e829f049b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 9 Aug 2009 03:47:32 +0200 Subject: [PATCH] completely factor out allocation/deallocation and placement new into a base class --- src/proc/control/command.cpp | 3 +- src/proc/control/typed-allocation-manager.hpp | 165 +++++++++++++++--- 2 files changed, 144 insertions(+), 24 deletions(-) diff --git a/src/proc/control/command.cpp b/src/proc/control/command.cpp index e3b6d58d7..ae42bf5c5 100644 --- a/src/proc/control/command.cpp +++ b/src/proc/control/command.cpp @@ -146,12 +146,13 @@ namespace control { Command Command::storeDef (Symbol newCmdID) { + CommandRegistry& registry = CommandRegistry::instance(); static format fmt("Unable to store %s as new command. ID \"%s\" is already in use"); + if (registry.queryIndex (newCmdID)) throw error::Logic (str (fmt % *this % newCmdID), LUMIERA_ERROR_DUPLICATE_COMMAND); Command cloneDefinition; - CommandRegistry& registry = CommandRegistry::instance(); cloneDefinition.activate (registry.createCloneImpl(impl())); return registry.track (newCmdID, cloneDefinition); diff --git a/src/proc/control/typed-allocation-manager.hpp b/src/proc/control/typed-allocation-manager.hpp index 5ce904261..397bc0e9f 100644 --- a/src/proc/control/typed-allocation-manager.hpp +++ b/src/proc/control/typed-allocation-manager.hpp @@ -73,7 +73,7 @@ //#include "lib/bool-checkable.hpp" -//#include +#include //#include //#include @@ -81,7 +81,7 @@ namespace control { -// using std::tr1::shared_ptr; + using std::tr1::shared_ptr; // using std::ostream; // using std::string; @@ -102,47 +102,166 @@ namespace control { + /* ======= managing the created objects ============= */ + /** opaque link to the manager, to be used by handles and + * smart-ptrs to trigger preconfigured destruction. */ template - struct Slot + class Killer { - typedef void DelFun(XOX*); + _TheManager* manager_; - void* const storage; - DelFun* const killer; + public: + void + operator() (XOX* victim) + { + REQUIRE (manager_); + ///////////////////////////////////////////////TODO: clean behaviour while in App shutdown (Ticket #196) + manager_->destroyElement (victim); + } protected: - Slot(void* sto, DelFun* kil) - : storage(sto) - , killer(kil) + Killer(_TheManager* m) + : manager_(m) { } - - friend class _TheManager; }; - - /** static entry point to be used by - * handles and smart pointers to trigger - * preconfigured destruction */ + /** a token representing a newly opened slot + * capable for holding an object of type XOX . + * The receiver is responsible for + * - either calling releaseSlot + * - or building a smart-ptr / handle wired to + * the \link #getDeleter deleter function \endlink + */ template - static void - kill (XOX* entry) + struct Slot + : private Killer { - ///////////////////////////////////////////////TODO: clean behaviour while in App shutdown (Ticket #196) - instance().destroyElement(entry); + /** pointer to the allocated storage + * with \c sizeof(XOX) bytes */ + void* const storage_; + + /** build a refcounting smart-ptr, + * complete with back-link to the manager + * for de-allocation */ + shared_ptr + build (XOX* toTrack) + { + return shared_ptr (toTrack, getDeleter()); + } + + Killer const& + getDeleter() + { + return *this; + } + + protected: + Slot(_TheManager* don, void* mem) + : Killer(don) + , storage_(mem) + { } + + friend class TypedAllocationManager; + }; + + + + + /* ==== build objects with managed allocation ==== */ + +#define _EXCEPTION_SAFE_INVOKE(_CTOR_) \ + \ + Slot slot = allocateSlot(); \ + try \ + { \ + return slot.build (new(slot.storage_) _CTOR_ ); \ + } \ + catch(...) \ + { \ + releaseSlot(slot.storage_); \ + throw; \ + } + + template< class XX> + shared_ptr //_____________________ + create () ///< invoke default ctor + { + _EXCEPTION_SAFE_INVOKE ( XX() ) } - ///////////////////TODO solve the problem how to re-access the instance from within the deletor + template< class XX, typename P1> + shared_ptr //___________________ + create (P1& p1) ///< invoke 1-arg ctor + { + _EXCEPTION_SAFE_INVOKE ( XX (p1) ) + } + + + template< class XX + , typename P1 + , typename P2 + > + shared_ptr //___________________ + create (P1& p1, P2& p2) ///< invoke 2-arg ctor + { + _EXCEPTION_SAFE_INVOKE ( XX (p1,p2) ) + } + + + template< class XX + , typename P1 + , typename P2 + , typename P3 + > + shared_ptr //___________________ + create (P1& p1, P2& p2, P3& p3) ///< invoke 3-arg ctor + { + _EXCEPTION_SAFE_INVOKE ( XX (p1,p2,p3) ) + } + + + template< class XX + , typename P1 + , typename P2 + , typename P3 + , typename P4 + > + shared_ptr //___________________ + create (P1& p1, P2& p2, P3& p3, P4& p4) ///< invoke 4-arg ctor + { + _EXCEPTION_SAFE_INVOKE ( XX (p1,p2,p3,p4) ) + } + + + template< class XX + , typename P1 + , typename P2 + , typename P3 + , typename P4 + , typename P5 + > + shared_ptr //___________________ + create (P1& p1, P2& p2, P3& p3, P4& p4, P5& p5) ///< invoke 5-arg ctor + { + _EXCEPTION_SAFE_INVOKE ( XX (p1,p2,p3,p4,p5) ) + } + +#undef _EXCEPTION_SAFE_INVOKE + + + + + protected: /* ======= Managed Allocation Implementation ========== */ - protected: template Slot allocateSlot () { UNIMPLEMENTED ("redirect to the corresponding pool allocator"); void* space = 0; - return Slot (space, &kill); + return Slot (this, space); } template @@ -160,7 +279,7 @@ namespace control { if (!entry) return; try { - entry->~IMP(); + entry->~XX(); } catch(...) {