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
** subsystem collapses unexpectedly, its root handler signals the subsystem
** runner to initiate emergency shutdown. However, the collapsed subsystem
** is already defunct at that point, which breaks the the general contract
** of prerequisite subsystems to be available in operative mode. Lumiera
** is already defunct at that point, which breaks the general contract of
** prerequisite subsystems to be available in operative mode. Lumiera
** is not built as a resilient service in that respect, but we also
** mandate for any parts not to cache essential work results in
** transient memory; actions are logged and performed for
@ -262,7 +262,7 @@ namespace lib {
std::unique_ptr<MOC> mock_;
SRV* origInstance_;
DependencyFactory<SRV> origFactory_;
Factory origFactory_;
public:
Local()
@ -286,7 +286,8 @@ namespace lib {
~Local()
{
restoreOriginalFactory (origInstance_, move(origFactory_));
}
origFactory_ = Factory{};
} // clear possibly leftover deleter
explicit
operator bool() const
@ -341,7 +342,7 @@ namespace lib {
static_assert (meta::_Fun<FUN>(),
"Need a Lambda or Function object to create a heap allocated instance");
using Fun = typename meta::_Fun<FUN>::Functor; // suitable type to store for later invocation
using Fun = typename meta::_Fun<FUN>::Functor; // suitable type to store for later invocation
using Res = typename meta::_Fun<FUN>::Ret;
using Sub = typename meta::Strip<Res>::TypePlain;

View file

@ -70,8 +70,8 @@
** ## Implementation and performance
**
** 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
** std::atomic to work around the known (rather theoretical) problems of this pattern.
** as Meyer's Singleton. Rather, Double Checked Locking of a Mutex is combined with
** an std::atomic to work around the known (rather theoretical) concurrency problems.
** Microbenchmarks indicate that this implementation technique ranges close to the
** 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
@ -107,10 +107,17 @@ namespace lib {
/**
* 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>
class DependencyFactory
// : util::MoveAssign //////////////////////////////////////////////TICKET #1059 : GCC-4.9 stubbornly picks the copy assignment
: util::NonCopyable
{
using Creator = std::function<OBJ*()>;
using Deleter = std::function<void()>;
@ -211,6 +218,7 @@ namespace lib {
{
return new TAR;
}
template<class ABS>
static meta::enable_if<std::is_abstract<ABS>,
ABS* >
@ -254,20 +262,23 @@ namespace lib {
template<class SRV>
class Depend
{
using Instance = std::atomic<SRV*>;
using Factory = DependencyFactory<SRV>;
using Lock = ClassLock<SRV, NonrecursiveLock_NoWait>;
static std::atomic<SRV*> instance;
static DependencyFactory<SRV> factory;
/* === shared per type === */
static Instance instance;
static Factory factory;
friend class DependInject<SRV>;
public:
/** Interface to be used by clients for retrieving the service instance.
* Manages the instance creation, lifecycle and access in multithreaded context.
* @return instance of class `SRV`. When used in default configuration,
* this service instance is a singleton
/**
* Interface to be used by clients for retrieving the service instance.
* Manages the instance creation, lifecycle and access in multithreaded context.
* @return instance of class `SRV`. When used in default configuration,
* the returned service instance is a singleton.
*/
SRV&
operator() ()

View file

@ -27697,9 +27697,9 @@
</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;"/>
<icon BUILTIN="pencil"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1522110563499" ID="ID_470760423" MODIFIED="1522113397796" TEXT="stets ausf&#xfc;hrend">
<icon BUILTIN="idea"/>
<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">
<icon BUILTIN="button_ok"/>
</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;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1522200249626" ID="ID_215336836" MODIFIED="1522382087401" TEXT="Freunschafts-f&#xe4;hig">
<icon BUILTIN="button_ok"/>
</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;"/>
<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 COLOR="#338800" CREATED="1522334796724" ID="ID_1080992734" MODIFIED="1522384890030" TEXT="Funktoren zusammenf&#xfc;hren">