DI: change to heap allocation for singletons
up to now we used placement into a static buffer. While this approach is somewhat cool, I can't see much practical benefit anymore, given that we use an elaborate framework which rules out the use of Meyers Singleton. And given that with C++11 we're able just to use std::unique_ptr to do all work. Moreover, the intended configurability will become much simpler by relying on a _closure_ to produce a heap-allocated instance for all cases likewise. The only possible problem I can see is that critical infrastructure might rely on failsafe creation of some singleton. Up to now this scenario remains theoretical however
This commit is contained in:
parent
e393d44e92
commit
eebe31aa7e
2 changed files with 48 additions and 23 deletions
|
|
@ -56,6 +56,7 @@ typedef unsigned int uint;
|
|||
#include <boost/noncopyable.hpp>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#define SHOW_TYPE(_TY_) \
|
||||
|
|
@ -75,39 +76,22 @@ using lib::meta::enable_if;
|
|||
class InstanceHolder
|
||||
: boost::noncopyable
|
||||
{
|
||||
/** storage for the service instance */
|
||||
char buff_[sizeof(TAR)];
|
||||
bool alive_ = false;
|
||||
std::unique_ptr<TAR> instance_;
|
||||
|
||||
|
||||
public:
|
||||
~InstanceHolder()
|
||||
{
|
||||
if (alive_)
|
||||
try {
|
||||
alive_ = false;
|
||||
reinterpret_cast<TAR&> (buff_). ~TAR();
|
||||
}
|
||||
catch(...)
|
||||
{ // no logging since we might be in static shutdown
|
||||
lumiera_error(); // reset errorflag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TAR*
|
||||
buildInstance()
|
||||
{
|
||||
if (alive_)
|
||||
if (instance_)
|
||||
throw error::Fatal("Attempt to double-create a singleton service. "
|
||||
"Either the application logic, or the compiler "
|
||||
"or runtime system is seriously broken"
|
||||
,error::LUMIERA_ERROR_LIFECYCLE);
|
||||
|
||||
// place new instance into embedded buffer
|
||||
TAR* newInstance = new(&buff_) TAR ();
|
||||
alive_ = true;
|
||||
return newInstance;
|
||||
instance_.reset (new TAR{});
|
||||
return instance_.get();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -232,7 +216,7 @@ main (int, char**)
|
|||
SHOW_EXPR( checksum );
|
||||
|
||||
Depend<Dum> dumm;
|
||||
Depend<Dum>::factory = [](){ return nullptr; };
|
||||
// Depend<Dum>::factory = [](){ return nullptr; };
|
||||
SHOW_EXPR( dumm().probe() );
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26993,7 +26993,48 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521169130251" ID="ID_1252056818" MODIFIED="1521169146081" TEXT="Zugang für DependInject">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521254014422" ID="ID_961824675" MODIFIED="1521254035254" TEXT="Meyers Singleton oder explizit ausprogrammieren?">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521324229082" ID="ID_1398878858" MODIFIED="1521324233702" TEXT="Storage">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1521324240124" ID="ID_1099103129" MODIFIED="1521324253936">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
statische Storage ist <i>irgendwie cool</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1521324275919" ID="ID_1710451095" MODIFIED="1521324497413" TEXT="sehe aber auch keinen wirklichen Vorteil">
|
||||
<node CREATED="1521324529228" ID="ID_1786667023" MODIFIED="1521324543094" TEXT="man muß sich nicht um die de-Allokation kümmern"/>
|
||||
<node CREATED="1521324554465" ID="ID_1577416641" MODIFIED="1521324568043" TEXT="Storage ist garantiert vorhanden, kein out-of-Memory"/>
|
||||
<node CREATED="1521324668449" ID="ID_1013908061" MODIFIED="1521324682434" TEXT="Meyers Singleton ist elegant und schnell"/>
|
||||
</node>
|
||||
<node CREATED="1521324321601" ID="ID_805959606" MODIFIED="1521324477609" TEXT="Nachteil: Storage ist stets belegt, auch wenn nicht notwendig">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
das gilt im Besonderen für eine default-Storage als Singleton.
|
||||
</p>
|
||||
<p>
|
||||
Wofern wir dynamisch konfigurieren (wollen), muß dieser Default stets statisch bereitgestellt werden,
|
||||
</p>
|
||||
<p>
|
||||
selbst wenn die dynamische Konfiguration so angelegt ist, daß die Storage nie benötigt wird
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1521324883035" ID="ID_1438637057" MODIFIED="1521324896069" TEXT="Heap-Allokation könnte insgesamt einfacher sein"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521254014422" ID="ID_961824675" MODIFIED="1521324200616" TEXT="Meyers Singleton oder explizit ausprogrammieren?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1521303577633" ID="ID_1665490706" MODIFIED="1521303615967" TEXT="das wäre die "Standard-Lösung" für Singletons"/>
|
||||
<node CREATED="1521303616675" ID="ID_135579041" MODIFIED="1521303721048" TEXT="hier aber nicht sinnvoll...">
|
||||
|
|
|
|||
Loading…
Reference in a new issue