DI: solve problem with leftover deleter in testmock. Unit test PASS

This commit is contained in:
Fischlurch 2018-03-30 07:42:53 +02:00
parent 5d0c2b6d2c
commit cc46c5b04b
3 changed files with 61 additions and 20 deletions

View file

@ -95,8 +95,8 @@
** @warning there is a known coherency breach in "emergency shutdown": When a ** @warning there is a known coherency breach in "emergency shutdown": When a
** subsystem collapses unexpectedly, its root handler signals the subsystem ** subsystem collapses unexpectedly, its root handler signals the subsystem
** runner to initiate emergency shutdown. However, the collapsed subsystem ** runner to initiate emergency shutdown. However, the collapsed subsystem
** is already defunct at that point, which breaks the the general contract ** is already defunct at that point, which breaks the general contract of
** of prerequisite subsystems to be available in operative mode. Lumiera ** prerequisite subsystems to be available in operative mode. Lumiera
** is not built as a resilient service in that respect, but we also ** is not built as a resilient service in that respect, but we also
** mandate for any parts not to cache essential work results in ** mandate for any parts not to cache essential work results in
** transient memory; actions are logged and performed for ** transient memory; actions are logged and performed for
@ -262,7 +262,7 @@ namespace lib {
std::unique_ptr<MOC> mock_; std::unique_ptr<MOC> mock_;
SRV* origInstance_; SRV* origInstance_;
DependencyFactory<SRV> origFactory_; Factory origFactory_;
public: public:
Local() Local()
@ -286,7 +286,8 @@ namespace lib {
~Local() ~Local()
{ {
restoreOriginalFactory (origInstance_, move(origFactory_)); restoreOriginalFactory (origInstance_, move(origFactory_));
} origFactory_ = Factory{};
} // clear possibly leftover deleter
explicit explicit
operator bool() const operator bool() const

View file

@ -70,8 +70,8 @@
** ## Implementation and performance ** ## Implementation and performance
** **
** Due to this option for flexible configuration, the implementation can not be built ** Due to this option for flexible configuration, the implementation can not be built
** as Meyer's Singleton. Rather, Double Checked Locking of a Mutex is combined with an ** as Meyer's Singleton. Rather, Double Checked Locking of a Mutex is combined with
** std::atomic to work around the known (rather theoretical) problems of this pattern. ** an std::atomic to work around the known (rather theoretical) concurrency problems.
** Microbenchmarks indicate that this implementation technique ranges close to the ** Microbenchmarks indicate that this implementation technique ranges close to the
** speed of a direct access to an already existing object; in the fully optimised ** speed of a direct access to an already existing object; in the fully optimised
** variant it was found to be roughly at 1ns and thus about 3 to 4 times slower ** variant it was found to be roughly at 1ns and thus about 3 to 4 times slower
@ -107,10 +107,17 @@ namespace lib {
/** /**
* Helper to abstract creation and lifecycle of a dependency * Helper to abstract creation and lifecycle of a dependency
* Holds a configurable constructor function and optionally
* an automatically invoked deleter function.
* @note DependencyFactory can be declared friend to indicate
* the expected way to invoke an otherwise private ctor.
* This is a classical idiom for singletons.
* @see lib::Depend
* @see lib::DependInject
*/ */
template<class OBJ> template<class OBJ>
class DependencyFactory class DependencyFactory
// : util::MoveAssign //////////////////////////////////////////////TICKET #1059 : GCC-4.9 stubbornly picks the copy assignment : util::NonCopyable
{ {
using Creator = std::function<OBJ*()>; using Creator = std::function<OBJ*()>;
using Deleter = std::function<void()>; using Deleter = std::function<void()>;
@ -211,6 +218,7 @@ namespace lib {
{ {
return new TAR; return new TAR;
} }
template<class ABS> template<class ABS>
static meta::enable_if<std::is_abstract<ABS>, static meta::enable_if<std::is_abstract<ABS>,
ABS* > ABS* >
@ -254,20 +262,23 @@ namespace lib {
template<class SRV> template<class SRV>
class Depend class Depend
{ {
using Instance = std::atomic<SRV*>;
using Factory = DependencyFactory<SRV>; using Factory = DependencyFactory<SRV>;
using Lock = ClassLock<SRV, NonrecursiveLock_NoWait>; using Lock = ClassLock<SRV, NonrecursiveLock_NoWait>;
static std::atomic<SRV*> instance; /* === shared per type === */
static DependencyFactory<SRV> factory; static Instance instance;
static Factory factory;
friend class DependInject<SRV>; friend class DependInject<SRV>;
public: public:
/** Interface to be used by clients for retrieving the service instance. /**
* Interface to be used by clients for retrieving the service instance.
* Manages the instance creation, lifecycle and access in multithreaded context. * Manages the instance creation, lifecycle and access in multithreaded context.
* @return instance of class `SRV`. When used in default configuration, * @return instance of class `SRV`. When used in default configuration,
* this service instance is a singleton * the returned service instance is a singleton.
*/ */
SRV& SRV&
operator() () operator() ()

View file

@ -27697,9 +27697,9 @@
</node> </node>
</node> </node>
</node> </node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522110414912" ID="ID_1861060212" MODIFIED="1522384924858" TEXT="Singleton-Erzeugung zusammenf&#xfc;hren"> <node COLOR="#338800" CREATED="1522110414912" ID="ID_1861060212" MODIFIED="1522388012137" TEXT="Singleton-Erzeugung zusammenf&#xfc;hren">
<linktarget COLOR="#5f8d94" DESTINATION="ID_1861060212" ENDARROW="Default" ENDINCLINATION="-566;0;" ID="Arrow_ID_319700222" SOURCE="ID_1624172022" STARTARROW="None" STARTINCLINATION="205;-440;"/> <linktarget COLOR="#5f8d94" DESTINATION="ID_1861060212" ENDARROW="Default" ENDINCLINATION="-566;0;" ID="Arrow_ID_319700222" SOURCE="ID_1624172022" STARTARROW="None" STARTINCLINATION="205;-440;"/>
<icon BUILTIN="pencil"/> <icon BUILTIN="button_ok"/>
<node CREATED="1522110563499" ID="ID_470760423" MODIFIED="1522113397796" TEXT="stets ausf&#xfc;hrend"> <node CREATED="1522110563499" ID="ID_470760423" MODIFIED="1522113397796" TEXT="stets ausf&#xfc;hrend">
<icon BUILTIN="idea"/> <icon BUILTIN="idea"/>
<node CREATED="1522110568307" ID="ID_311971109" MODIFIED="1522110579069" TEXT="Depend&lt;SUB&gt;"/> <node CREATED="1522110568307" ID="ID_311971109" MODIFIED="1522110579069" TEXT="Depend&lt;SUB&gt;"/>
@ -27796,18 +27796,47 @@
<node COLOR="#338800" CREATED="1522200189706" ID="ID_302642427" MODIFIED="1522382084962" TEXT="m&#xf6;glichst alle instance-Pointer zur&#xfc;cksetzen"> <node COLOR="#338800" CREATED="1522200189706" ID="ID_302642427" MODIFIED="1522382084962" TEXT="m&#xf6;glichst alle instance-Pointer zur&#xfc;cksetzen">
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
</node> </node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522384942847" ID="ID_1152640572" MODIFIED="1522385141698" TEXT="Fehlermeldung beim Zugriff nach Zerst&#xf6;rung"> <node COLOR="#338800" CREATED="1522384942847" ID="ID_1152640572" MODIFIED="1522387791802" TEXT="Fehlermeldung beim Zugriff nach Zerst&#xf6;rung">
<linktarget COLOR="#639d9e" DESTINATION="ID_1152640572" ENDARROW="Default" ENDINCLINATION="-89;0;" ID="Arrow_ID_1512382393" SOURCE="ID_1741501987" STARTARROW="None" STARTINCLINATION="28;-1;"/> <linktarget COLOR="#639d9e" DESTINATION="ID_1152640572" ENDARROW="Default" ENDINCLINATION="-89;0;" ID="Arrow_ID_1512382393" SOURCE="ID_1741501987" STARTARROW="None" STARTINCLINATION="28;-1;"/>
<icon BUILTIN="flag-yellow"/> <icon BUILTIN="button_ok"/>
</node> </node>
<node COLOR="#338800" CREATED="1522200249626" ID="ID_215336836" MODIFIED="1522382087401" TEXT="Freunschafts-f&#xe4;hig"> <node COLOR="#338800" CREATED="1522200249626" ID="ID_215336836" MODIFIED="1522382087401" TEXT="Freunschafts-f&#xe4;hig">
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
</node> </node>
</node> </node>
</node> </node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1522384902500" ID="ID_1741501987" MODIFIED="1522385141698" TEXT="Zugriff beim Herunterfahren"> <node COLOR="#338800" CREATED="1522384902500" ID="ID_1741501987" MODIFIED="1522387795093" TEXT="Zugriff beim Herunterfahren">
<arrowlink COLOR="#639d9e" DESTINATION="ID_1152640572" ENDARROW="Default" ENDINCLINATION="-89;0;" ID="Arrow_ID_1512382393" STARTARROW="None" STARTINCLINATION="28;-1;"/> <arrowlink COLOR="#639d9e" DESTINATION="ID_1152640572" ENDARROW="Default" ENDINCLINATION="-89;0;" ID="Arrow_ID_1512382393" STARTARROW="None" STARTINCLINATION="28;-1;"/>
<icon BUILTIN="flag-pink"/> <icon BUILTIN="button_ok"/>
<node CREATED="1522387798572" HGAP="35" ID="ID_1522844249" MODIFIED="1522387935592" TEXT="war ein &#xfc;briggebliebener Destruktor in einem Mock" VSHIFT="12">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
zwar wird beim L&#246;schen des Mock
</p>
<p>
die urspr&#252;ngliche Factory wieder an ihren Platz zur&#252;ckgeschoben,
</p>
<p>
aber niemand sagt, da&#223; ein Move auch wirklich ein Move (swap) ist.
</p>
<p>
Mu&#223; daher diese leer gewordene tempor&#228;re Factory explizit auf Default-Zustand zur&#252;cksetzen,
</p>
<p>
damit nicht doch noch der Deleter l&#228;uft.
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="ksmiletris"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522387936585" ID="ID_1922190351" MODIFIED="1522388036540" TEXT="es w&#xe4;re besser, wenn Factory &#xfc;berhaupt nicht assignable w&#xe4;re">
<icon BUILTIN="flag-yellow"/>
</node>
</node> </node>
</node> </node>
<node COLOR="#338800" CREATED="1522334796724" ID="ID_1080992734" MODIFIED="1522384890030" TEXT="Funktoren zusammenf&#xfc;hren"> <node COLOR="#338800" CREATED="1522334796724" ID="ID_1080992734" MODIFIED="1522384890030" TEXT="Funktoren zusammenf&#xfc;hren">