DI: (WIP) switch to totally rewritten new implementation of lib::Depend (#1086)
- state-of-the-art implementation of access with Double Checked Locking + Atomics - improved design for configuration of dependencies. Now at the provider, not the consumer - support for exposing services with a lifecycle through the lib::Depend<SRV> front-end
This commit is contained in:
parent
043dc948e3
commit
80207ea224
19 changed files with 105 additions and 131 deletions
|
|
@ -50,7 +50,7 @@
|
|||
typedef unsigned int uint;
|
||||
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/depend2.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
//#include "lib/meta/util.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
|
|
|
|||
|
|
@ -28,18 +28,18 @@
|
|||
** plants an instance of lib::Depend, templated to the actual type of the dependency.
|
||||
** This is a way to express the dependency on some interface or service, while not
|
||||
** expanding on any details as to when and how this dependency is created. Without
|
||||
** and explicit configuration, lib::Depend will automatically create and manage a
|
||||
** an explicit configuration, lib::Depend will automatically create and manage a
|
||||
** singleton instance of the type given as type parameter.
|
||||
**
|
||||
** ## Architecture
|
||||
** A _dependency_ is understood as something we need to do the task at hand, yet
|
||||
** a dependency lies beyond that task and relates to concerns outside the scope
|
||||
** and theme of this actual task. The usage site of the dependency is only bound
|
||||
** and coupled to the _interface_ exposed as dependency, and the associated
|
||||
** A _dependency_ is understood as something we need to perform the task at hand,
|
||||
** yet a dependency referres beyond that task and relates to concerns outside the
|
||||
** scope and theme of this actual task. The usage site of the dependency is only
|
||||
** bound and coupled to the _interface_ exposed as dependency, and the associated
|
||||
** _contract_ of a service. Initially, such a dependency is _dormant_ and will
|
||||
** be activated on first access. This simplifies the bootstrap of complex
|
||||
** be activated on first access. This simplifies the bootstrap of complexly
|
||||
** interwoven structures; it suffices to ensure that none of the participating
|
||||
** entities actually starts to work before all of the setup and wiring is done.
|
||||
** entities actually starts its work before all of the setup and wiring is done.
|
||||
**
|
||||
** For that reason, lib::DependInject<SRV> is meant to be used at the site providing
|
||||
** the _actual_ service or implementation subtype -- not at the site consuming a
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
** function, a functor or lambda can be installed into the static factory of lib::Depend.
|
||||
** Especially, a lambda could be bound into the internal context of the service provider.
|
||||
** This function is expected to deliver a heap allocated instance on invocation, which
|
||||
** will be owned and managed by lib::Depend<SRV>::singleton (An InstanceHolder<SRV>).
|
||||
** will be owned and managed by lib::Depend<SRV>::factory (A DependencyFactory<SRV>).
|
||||
**
|
||||
** \paragraph Service Lifecycle
|
||||
** Whenever a module or subsystem can be started and stopped, several interconnected
|
||||
|
|
@ -117,7 +117,7 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/depend2.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/sync-classlock.hpp"
|
||||
|
|
@ -139,9 +139,9 @@ namespace lib {
|
|||
/**
|
||||
* This framework allows to (re)configure the lib::Depend front-end for dependency-injection.
|
||||
* By default, `Depend<TY>` will create a singleton instance of `TY` lazily, on demand.
|
||||
* When instantiating one of the configuration handles provided here -- _prior_ to using
|
||||
* When instantiating one of the configuration handles provided here -- _prior_ to anyone
|
||||
* retrieving the instance through `Depend<TY>` -- this default (singleton) behaviour
|
||||
* can be reconfigured in various ways, without the client being aware of it
|
||||
* can be reconfigured in various ways, without the client being aware of it:
|
||||
* - instead of a singleton, a service instance with well defined lifecycle can be
|
||||
* exposed through the `Depend<TY>` front-end. When the service is shut down,
|
||||
* clients will receive an exception on access.
|
||||
|
|
@ -150,6 +150,7 @@ namespace lib {
|
|||
* singleton type, which still happens lazily, on demand
|
||||
* - the current state and configuration can be shadowed temporarily by a test mock instance,
|
||||
* which is managed automatically and removed when leaving the scope of the test.
|
||||
* @note DependInject<SRV> is declared fried by Depend<SRV> to reconfigure the latter's internals
|
||||
*/
|
||||
template<class SRV>
|
||||
class DependInject
|
||||
|
|
@ -159,7 +160,7 @@ namespace lib {
|
|||
using Lock = typename Depend<SRV>::Lock;
|
||||
|
||||
public:
|
||||
/** configure dependency-injection for type SRV to build a subclass singleton
|
||||
/** configure dependency-injection for type SRV to build a subclass singleton.
|
||||
* @note actually a delegation to `Depend<SUB>` is installed into `Depend<SRV>`
|
||||
* @tparam SUB concrete subclass type to build on demand when invoking `Depend<SRV>`
|
||||
* @throws error::Logic (LUMIERA_ERROR_LIFECYCLE) when the default factory has already
|
||||
|
|
@ -174,19 +175,19 @@ namespace lib {
|
|||
}
|
||||
|
||||
/** configure dependency-injection for type SRV to manage a subclass singleton,
|
||||
* which is created lazily on demand by invoking the given builder function
|
||||
* which is created lazily on demand by invoking the given builder function.
|
||||
* @note actual Subclass type is determined from the given functor and then
|
||||
* a delegation to `Depend<Subclass>` is installed into `Depend<SRV>`
|
||||
* @param ctor functor to create a heap allocated instance of subclass
|
||||
* @param ctor functor to create a heap allocated instance of the subclass
|
||||
* @throws error::Logic (LUMIERA_ERROR_LIFECYCLE) when the default factory has already
|
||||
* been invoked at the point when calling this (re)configuration function.
|
||||
*/
|
||||
template<class FUN>
|
||||
static void
|
||||
useSingleton(FUN&& ctor)
|
||||
useSingleton (FUN&& ctor)
|
||||
{
|
||||
using Fun = typename SubclassFactoryType<FUN>::Fun;
|
||||
using Sub = typename SubclassFactoryType<FUN>::Sub;
|
||||
using Sub = typename SubclassFactoryType<FUN>::Subclass;
|
||||
using Fun = typename SubclassFactoryType<FUN>::Functor;
|
||||
|
||||
__assert_compatible<Sub>();
|
||||
installFactory<Sub,Fun> (forward<FUN> (ctor));
|
||||
|
|
@ -214,7 +215,7 @@ namespace lib {
|
|||
public:
|
||||
template<typename...ARGS>
|
||||
ServiceInstance(ARGS&& ...ctorArgs)
|
||||
: instance_(new IMP(forward<ARGS> (ctorArgs)...))
|
||||
: instance_{new IMP(forward<ARGS> (ctorArgs)...)}
|
||||
{
|
||||
__assert_compatible<IMP>();
|
||||
activateServiceAccess (*instance_);
|
||||
|
|
@ -239,7 +240,7 @@ namespace lib {
|
|||
}
|
||||
|
||||
IMP*
|
||||
operator-> () const
|
||||
operator->() const
|
||||
{
|
||||
ENSURE (instance_);
|
||||
return instance_.get();
|
||||
|
|
@ -274,7 +275,7 @@ namespace lib {
|
|||
Local (FUN&& buildInstance)
|
||||
{
|
||||
__assert_compatible<MOC>();
|
||||
__assert_compatible<typename SubclassFactoryType<FUN>::Sub>();
|
||||
__assert_compatible<typename SubclassFactoryType<FUN>::Subclass>();
|
||||
|
||||
temporarilyInstallAlternateFactory (origInstance_, origFactory_
|
||||
,[=]()
|
||||
|
|
@ -341,11 +342,11 @@ 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 Res = typename meta::_Fun<FUN>::Ret;
|
||||
using Sub = typename meta::Strip<Res>::TypePlain;
|
||||
using Functor = typename meta::_Fun<FUN>::Functor; // suitable type to store for later invocation
|
||||
using ResultVal = typename meta::_Fun<FUN>::Ret;
|
||||
using Subclass = typename meta::Strip<ResultVal>::TypePlain;
|
||||
|
||||
static_assert (std::is_pointer<Res>::value,
|
||||
static_assert (std::is_pointer<ResultVal>::value,
|
||||
"Function must yield a pointer to a heap allocated instance");
|
||||
};
|
||||
|
||||
|
|
@ -378,6 +379,7 @@ namespace lib {
|
|||
__ensure_pristine();
|
||||
Depend<SRV>::factory.defineCreator ([]{ return & Depend<SUB>{}(); });
|
||||
}
|
||||
// note: we do not install an actual factory; rather we use the default for SUB
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -424,4 +426,4 @@ namespace lib {
|
|||
|
||||
|
||||
} // namespace lib
|
||||
#endif
|
||||
#endif /*LIB_DEPEND_INJECT_H*/
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef WIP_LIB_DEPEND_H
|
||||
#define WIP_LIB_DEPEND_H
|
||||
#ifndef LIB_DEPEND_H
|
||||
#define LIB_DEPEND_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
|
|
@ -324,4 +324,4 @@ namespace lib {
|
|||
|
||||
|
||||
} // namespace lib
|
||||
#endif
|
||||
#endif /*LIB_DEPEND_H*/
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "backend/media-access-facade.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include "proc/asset/asset-diagnostics.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
|
||||
using lib::test::Depend4Test;
|
||||
using util::isnil;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include "proc/asset/testasset.hpp"
|
||||
#include "proc/asset/asset-diagnostics.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "proc/asset/clip.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include "proc/asset/asset-diagnostics.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
|
||||
using lib::test::Depend4Test;
|
||||
using util::isnil;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include "proc/mobject/session/clip.hpp"
|
||||
#include "proc/asset/asset-diagnostics.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
|
||||
using lib::test::Depend4Test;
|
||||
using util::contains;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#include "proc/asset/asset-diagnostics.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
|
||||
using lib::test::Depend4Test;
|
||||
using util::isnil;
|
||||
|
|
|
|||
|
|
@ -34,13 +34,12 @@
|
|||
#include "proc/mobject/session/clip.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
using util::cStr;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
//#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
#include "proc/mobject/session/clip.hpp"
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "proc/mobject/session/testclip.hpp"
|
||||
#include "backend/media-access-facade.hpp"
|
||||
#include "backend/media-access-mock.hpp"
|
||||
#include "lib/test/depend-4test.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "proc/asset/clip.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include "lib/depend2.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
#include "lib/format-obj.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include "lib/depend2.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "test-target-obj.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#include "lib/util.hpp"
|
||||
|
||||
#include "test-target-obj.hpp"
|
||||
#include "lib/depend2.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "lib/util.hpp"
|
||||
|
||||
#include "test-target-obj.hpp"
|
||||
#include "lib/depend2.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -26507,8 +26507,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521843907144" ID="ID_848033940" MODIFIED="1521843935500" TEXT="Ergebnis normieren auf einzelnen Aufruf">
|
||||
|
|
@ -26527,8 +26526,7 @@
|
|||
habe einen usleep(1000) getimed
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -26561,8 +26559,7 @@
|
|||
Außerdem ist ja auch noch der Aufruf des Funktors mit im Spiel, wenngleich der auch typischerweise geinlined wird
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1521844236539" ID="ID_176799135" MODIFIED="1521844248411" TEXT="tatsächlich verifiziert">
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -26583,8 +26580,7 @@
|
|||
volatile Variable <i>außen,</i> im Aufrufkontext
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521844366944" ID="ID_1258575129" MODIFIED="1521844373484" TEXT="Zugriff via Closure und Referenz"/>
|
||||
<node CREATED="1521844374503" ID="ID_1548234021" MODIFIED="1521844386090" TEXT="diese Variable mit Konstante vergleichen"/>
|
||||
|
|
@ -26603,8 +26599,7 @@
|
|||
daß x86_64 tatsächlich cache-kohärent ist
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -26869,15 +26864,25 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1520722136029" ID="ID_1922898574" MODIFIED="1520722144366" TEXT="Problem: double checked locking">
|
||||
<node COLOR="#338800" CREATED="1520722136029" ID="ID_1922898574" MODIFIED="1522421599316" TEXT="Problem: double checked locking">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1520725664365" ID="ID_1453945091" MODIFIED="1520725671423" TEXT="was bringt C++11?">
|
||||
<node CREATED="1520725673123" ID="ID_574000501" LINK="http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/" MODIFIED="1520726129608" TEXT="Jeff Preshings: double-checked-locking-is-fixed-in-cpp11"/>
|
||||
<node CREATED="1520726409894" ID="ID_1296403824" LINK="http://www.modernescpp.com/index.php/thread-safe-initialization-of-a-singleton" MODIFIED="1520726425377" TEXT="Rainer Grimm: thread local initialization of singletons"/>
|
||||
</node>
|
||||
<node CREATED="1520726342863" ID="ID_1875729983" MODIFIED="1520726350066" TEXT="moderne Lösung">
|
||||
<node CREATED="1520726350894" ID="ID_47446040" MODIFIED="1520726354025" TEXT="Atomics"/>
|
||||
<node CREATED="1520726354878" ID="ID_1241761015" MODIFIED="1520726363168" TEXT="vorgeschaltetes thread_local">
|
||||
<node COLOR="#338800" CREATED="1520726342863" FOLDED="true" ID="ID_1875729983" MODIFIED="1522421593574" TEXT="moderne Lösung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1520726350894" ID="ID_47446040" MODIFIED="1522421521283" TEXT="Atomics">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1522421526272" ID="ID_406901713" MODIFIED="1522421532577" TEXT="Performance sehr gut"/>
|
||||
<node CREATED="1522421537122" ID="ID_1012365029" MODIFIED="1522421553659" TEXT="nahe an einem direkten lokalen Zugriff"/>
|
||||
<node CREATED="1522421554271" ID="ID_1930807074" MODIFIED="1522421564034" TEXT="etwa halb so schnell wie DCL alleine"/>
|
||||
<node CREATED="1522421564582" ID="ID_596046075" MODIFIED="1522421575992" TEXT="Zugriff etwa 1 Nanosekunde">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1520726354878" ID="ID_1241761015" MODIFIED="1522421518773" TEXT="vorgeschaltetes thread_local">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1520726364612" ID="ID_818685184" MODIFIED="1520726369804" TEXT="Performance nicht klar">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
|
|
@ -27433,8 +27438,7 @@
|
|||
<u>Thema</u>: Memory access order constraints
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#5a6caa" DESTINATION="ID_1416813337" ENDARROW="Default" ENDINCLINATION="-1755;162;" ID="Arrow_ID_751165448" STARTARROW="None" STARTINCLINATION="-4287;-237;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1521783335195" ID="ID_594004742" LINK="http://en.cppreference.com/w/cpp/atomic/memory_order" MODIFIED="1521783351104" TEXT="CPP-Reference"/>
|
||||
|
|
@ -27449,8 +27453,7 @@
|
|||
<font color="#45317b">Grundidee</font>: <b>synchronizes-with</b>-Beziehung herstellen <i>auf Guard-Variable</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521788423421" FOLDED="true" ID="ID_992901826" MODIFIED="1521882883828" TEXT="use-cases">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
|
|
@ -27474,8 +27477,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521788638623" ID="ID_16016457" MODIFIED="1521788679409">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -27490,8 +27492,7 @@
|
|||
auf einer temporären lokalen Instanz-Variable zu arbeiten
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -27519,8 +27520,7 @@
|
|||
die verschiedenen Belange im Quelltext nicht zu vermischen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -27548,8 +27548,7 @@
|
|||
Daher werfen wir ja auch error::Fatal
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1521789511870" ID="ID_553276693" MODIFIED="1521789526160" TEXT="Konsistenz-check und Service-Start im Mutex sind ausreichend"/>
|
||||
|
|
@ -27566,8 +27565,7 @@
|
|||
das auch in fehlerhaftem Double-Checked-Locking auftritt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1521789904872" ID="ID_1237807951" MODIFIED="1521789930400" TEXT="...was aber durch den default (memory_order_seq_cst) mit impliziert ist">
|
||||
|
|
@ -27598,8 +27596,7 @@
|
|||
der andere Thread ihn grade nutzt.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521790222356" ID="ID_168283882" MODIFIED="1521790445457">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -27614,8 +27611,7 @@
|
|||
daß dieser Fall nicht relevant ist
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -27642,8 +27638,7 @@
|
|||
daß dieser "andere Thread" nicht (mehr) aktiv sein darf, wenn der Shutdown erfolgt.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521790458636" ID="ID_1895342635" MODIFIED="1521791087780" TEXT="Ausnahme: Emergency-Shutdown">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
|
|
@ -27660,8 +27655,7 @@
|
|||
hier ist ein <b>Segfault</b> möglich
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -27689,8 +27683,7 @@
|
|||
...denn wir sind auf x86_64 -- und diese Plattform ist per default <i>fast überall</i> sequentially coherent
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521866206751" ID="ID_702466096" MODIFIED="1521882798384" TEXT="Bezugspunkt: Zugriff auf bereits existierenden Service">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -27759,8 +27752,7 @@
|
|||
Der kaskadierende Aufruf liest dann einfach <i>dessen</i> Instanz-Pointer
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1522110531344" ID="ID_1376369013" MODIFIED="1522110534779" TEXT="custom-ctor">
|
||||
|
|
@ -27780,8 +27772,7 @@
|
|||
Das könnte mit dem Factory-Management einer bereits installierten Konfiguration kollidieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1522112400703" ID="ID_1562178283" MODIFIED="1522112404258" TEXT="Factory erstellen"/>
|
||||
</node>
|
||||
|
|
@ -27845,8 +27836,7 @@
|
|||
damit nicht doch noch der Deleter läuft.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1522387936585" ID="ID_1922190351" MODIFIED="1522388778471" TEXT="es wäre besser, wenn Factory überhaupt nicht assignable wäre">
|
||||
|
|
@ -27859,8 +27849,7 @@
|
|||
...und man stattdessen explizit eine <i>gefährliche Funktion</i>  aufrufen muß
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -27979,8 +27968,7 @@
|
|||
Konsequenz: das ist <b>keine Library-Implementierung</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521790951152" ID="ID_974126504" MODIFIED="1521946981024" TEXT="Semantik der Konfigurations-Varianten beschreiben">
|
||||
|
|
@ -28020,7 +28008,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1520722160591" ID="ID_135546699" MODIFIED="1520722168810" TEXT="Unit-Test">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1520722160591" ID="ID_135546699" MODIFIED="1522421617782" TEXT="Unit-Test">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1521419576303" ID="ID_726128967" MODIFIED="1522042418343" TEXT="alte Tests portieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1521418937870" ID="ID_906296527" MODIFIED="1522033081893" TEXT="Singleton_test">
|
||||
|
|
@ -28081,8 +28070,7 @@
|
|||
die von der alten DependencyFactory abhängen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#b8154d" DESTINATION="ID_278956866" ENDARROW="Default" ENDINCLINATION="32;436;" ID="Arrow_ID_1985884795" SOURCE="ID_513111416" STARTARROW="None" STARTINCLINATION="223;-69;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522033940685" ID="ID_447878554" MODIFIED="1522034123685" TEXT="media-access-mock-test.cpp">
|
||||
|
|
@ -28120,9 +28108,10 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1520722155112" ID="ID_1512641426" MODIFIED="1520722159028" TEXT="Integration">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521160755182" ID="ID_678080556" MODIFIED="1521160802831" TEXT="Umbenennen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1520722155112" ID="ID_1512641426" MODIFIED="1522421627198" TEXT="Integration">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1521160755182" ID="ID_678080556" MODIFIED="1522428573233" TEXT="Umbenennen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521160765588" ID="ID_1857896991" MODIFIED="1521160801792" TEXT="Konfig-Aufrufe anpassen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -28157,8 +28146,7 @@
|
|||
Und dann wäre es ziemlich pervasiv, sowas zum Freund zu erklären.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1522388857786" ID="ID_1151074517" MODIFIED="1522389011363">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -28170,8 +28158,7 @@
|
|||
<b>DependencyFactory</b> ist viel besser geeignet
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -29859,8 +29846,7 @@
|
|||
das sind verschiedene Blickwinkel auf das gleiche Thema
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1521779467554" ID="ID_257299836" MODIFIED="1521779468925" TEXT="fence">
|
||||
<node CREATED="1521779469969" ID="ID_178160333" MODIFIED="1521779473476" TEXT="total-global"/>
|
||||
|
|
@ -29887,8 +29873,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<node CREATED="1521779549150" ID="ID_754401646" MODIFIED="1521779560424" TEXT="ReadRead"/>
|
||||
<node CREATED="1521779561540" ID="ID_177816200" MODIFIED="1521779564336" TEXT="ReadWrite"/>
|
||||
<node CREATED="1521779565188" ID="ID_1059751946" MODIFIED="1521779570999" TEXT="WriteWrite"/>
|
||||
|
|
@ -29922,8 +29907,7 @@
|
|||
eine <i>Solche</i> konstituiert die synchronizes-with-Beziehuung
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -29937,8 +29921,7 @@
|
|||
<b>Grundbeziehung</b>: synchronizes-with
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -29960,8 +29943,7 @@
|
|||
das gilt nur im Rahmen der <b>synchronizes-with</b>-Beziehung
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521780488708" ID="ID_945270217" MODIFIED="1521780517520">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -29973,8 +29955,7 @@
|
|||
das heißt, nur für einen <b>vom gleichen Mutex geschützen</b>  Bereich!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521782262223" HGAP="30" ID="ID_1323377815" MODIFIED="1521782807539" TEXT="Typisches Gegenbeispiel: Double Checked Locking" VSHIFT="18">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -30007,8 +29988,7 @@
|
|||
Allerdinsg nicht auf einer Plattform, die ohnehin sequentiell-konsistent ist. Wie "zum Beispiel" x86/64
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -30023,8 +30003,7 @@
|
|||
...haben wir es hier mit einem <b>Pattern</b> zu tun
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521791417311" ID="ID_668833788" MODIFIED="1521791528549">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -30036,8 +30015,7 @@
|
|||
ich nenne es "<b>synchronised visibility cones</b>"
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521791441996" ID="ID_656786136" MODIFIED="1521791513129">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -30055,8 +30033,7 @@
|
|||
In Realität arbeiten mehrere Threads/Cores mit mehreren Entitäten
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1521791567491" ID="ID_328701027" MODIFIED="1521791613112" TEXT="Code muß das Bestehen der Beziehung aktiv prüfen">
|
||||
|
|
@ -30072,8 +30049,7 @@
|
|||
die shared zone anzufassen!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -31283,8 +31259,7 @@
|
|||
END
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1522025982759" ID="ID_1830638050" MODIFIED="1522025987194" TEXT="reproduzierbar....">
|
||||
<node CREATED="1522025990246" ID="ID_261366619" MODIFIED="1522026014541" TEXT="Auf mehreren Terminals x-mal starten">
|
||||
|
|
@ -31348,8 +31323,7 @@
|
|||
weil sich die Threads gegenseitig ihre Counter inkrementieren.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1522029979544" ID="ID_1820534569" MODIFIED="1522030021122" TEXT="Streßtest wiederholt, sogar mit 500 Thrads"/>
|
||||
<node COLOR="#338800" CREATED="1522029995205" ID="ID_556688250" MODIFIED="1522030021122" TEXT="jetzt reproduzierbar alles sauber">
|
||||
|
|
@ -31374,8 +31348,7 @@
|
|||
verwenden globale Variable oder überhaupt keine Objektfelder
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue