From 29ee5131f48c7582a38670d1431ee94b933bbbdd Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 2 Apr 2018 04:19:17 +0200 Subject: [PATCH] Switch first Layer-Separation-Interface to expose the service implementation via lib::Depend Actually this is on the implementation side only. Since Layer-Separation-Interfaces route each call through a binding layer, we get two Service-"Instances" to manage - on the client side we have to route into the Lumiera Interface system - on the implementation side the C-Language calls from the Interface system need to get to the actual service implementation. The latter is now managed and exposed via DependInject::ServiceInstance --- src/lib/depend-inject.hpp | 31 ++++++++++++++++++-- src/lib/depend.hpp | 11 +++++++ src/proc/control/proc-dispatcher.cpp | 16 +++++----- src/proc/control/session-command-service.cpp | 22 +++++++------- src/proc/control/session-command-service.hpp | 26 +++++++--------- wiki/thinkPad.ichthyo.mm | 22 ++++++++++++-- 6 files changed, 89 insertions(+), 39 deletions(-) diff --git a/src/lib/depend-inject.hpp b/src/lib/depend-inject.hpp index 7e3238fcb..da5366b16 100644 --- a/src/lib/depend-inject.hpp +++ b/src/lib/depend-inject.hpp @@ -206,7 +206,7 @@ namespace lib { * @throws error::Logic (LUMIERA_ERROR_LIFECYCLE) when the default factory has already * been invoked at the point when calling this (re)configuration function. */ - template + template class ServiceInstance : util::MoveOnly { @@ -221,11 +221,38 @@ namespace lib { activateServiceAccess (*instance_); } + /** create in deactivated state. Can be [activated](\ref #createInstance) later */ + ServiceInstance() + : instance_{} + { + __assert_compatible(); + } + ~ServiceInstance() { - deactivateServiceAccess(); + shutdown(); } + template + IMP& + createInstance(ARGS&& ...ctorArgs) + { + instance_.reset (new IMP(forward (ctorArgs)...)); + activateServiceAccess (*instance_); + return *instance_; + } + + void + shutdown() noexcept + { + if (instance_) + { + deactivateServiceAccess(); + instance_.reset(); + } + } + + explicit operator bool() const { diff --git a/src/lib/depend.hpp b/src/lib/depend.hpp index f0579850a..9e44a1d8a 100644 --- a/src/lib/depend.hpp +++ b/src/lib/depend.hpp @@ -313,6 +313,17 @@ namespace lib { ENSURE (object); return *object; } + + + /** + * allow to "peek" if a dependency is already available and exposed. + * @remark relevant when C code relies on a service with lifecycle. + */ + explicit + operator bool() const + { + return instance.load (std::memory_order_acquire); + } }; diff --git a/src/proc/control/proc-dispatcher.cpp b/src/proc/control/proc-dispatcher.cpp index fced93dd6..e1c6e598e 100644 --- a/src/proc/control/proc-dispatcher.cpp +++ b/src/proc/control/proc-dispatcher.cpp @@ -89,6 +89,7 @@ #include "proc/control/session-command-service.hpp" #include "proc/mobject/session.hpp" #include "backend/thread-wrapper.hpp" +#include "lib/depend-inject.hpp" #include "lib/util.hpp" ///////////////TODO for test command invocation #include @@ -116,9 +117,10 @@ namespace control { , public CommandDispatch , public Sync { + using ServiceHandle = lib::DependInject::ServiceInstance<>; /** manage the primary public Session interface */ - unique_ptr commandService_; + ServiceHandle commandService_; CommandQueue queue_; Looper looper_; @@ -135,8 +137,8 @@ namespace control { */ DispatcherLoop (Subsys::SigTerm notification) : Thread{"Lumiera Session", bind (&DispatcherLoop::runSessionThread, this, notification)} - , commandService_() - , queue_() + , commandService_{} + , queue_{} , looper_([&]() -> bool { return not queue_.empty(); @@ -145,15 +147,15 @@ namespace control { Thread::sync(); // done with setup; loop may run now.... INFO (session, "Proc-Dispatcher running..."); { - Lock(this); // open public session interface: - commandService_.reset(new SessionCommandService(*this)); + Lock(this); // open public session interface: + commandService_.createInstance(*this); } } ~DispatcherLoop() { try { - commandService_.reset(); // redundant call, to ensure session interface is closed reliably + commandService_.shutdown(); // redundant call, to ensure session interface is closed reliably INFO (session, "Proc-Dispatcher stopped."); } ERROR_LOG_AND_IGNORE(session, "Stopping the Proc-Dispatcher"); @@ -181,7 +183,7 @@ namespace control { requestStop() noexcept { Lock sync(this); - commandService_.reset(); // closes Session interface + commandService_.shutdown(); // closes Session interface looper_.triggerShutdown(); sync.notifyAll(); } diff --git a/src/proc/control/session-command-service.cpp b/src/proc/control/session-command-service.cpp index 196c1d477..4f3915bae 100644 --- a/src/proc/control/session-command-service.cpp +++ b/src/proc/control/session-command-service.cpp @@ -189,9 +189,8 @@ namespace control { using lumiera::facade::LUMIERA_ERROR_FACADE_LIFECYCLE; - typedef lib::SingletonRef::Accessor InstanceRef; - InstanceRef _instance; ///< a backdoor for the C Language impl to access the actual SessionCommand implementation... + lib::Depend _instance; ///< a backdoor for the C Language impl to access the actual SessionCommand implementation... @@ -206,7 +205,7 @@ namespace control { if (!_instance) return lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cmdID); else - return _instance->cycle(cmdID, invocationID); + return _instance().cycle(cmdID, invocationID); } ) , LUMIERA_INTERFACE_INLINE (trigger, @@ -214,7 +213,7 @@ namespace control { { if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cmdID); else - _instance->trigger(cmdID, *static_cast (args)); + _instance().trigger(cmdID, *static_cast (args)); } ) , LUMIERA_INTERFACE_INLINE (bindArg, @@ -222,7 +221,7 @@ namespace control { { if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cmdID); else - _instance->bindArg(cmdID, *static_cast (args)); + _instance().bindArg(cmdID, *static_cast (args)); } ) , LUMIERA_INTERFACE_INLINE (invoke, @@ -230,7 +229,7 @@ namespace control { { if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cmdID); else - _instance->invoke(cmdID); + _instance().invoke(cmdID); } ) ); @@ -241,15 +240,14 @@ namespace control { - - SessionCommandService::SessionCommandService (CommandDispatch& dispatcherLoopInterface) + /** @remark actual instance created from within ProcDispatcher */ + SessionCommandService::SessionCommandService (CommandDispatch& dispatcherLoopInterface) : dispatcher_{dispatcherLoopInterface} , instanceManager_{dispatcher_} - , implInstance_{this,_instance} , serviceInstance_{ LUMIERA_INTERFACE_REF (lumieraorg_SessionCommand, 0, lumieraorg_SessionCommandService)} - { - INFO (gui, "SessionCommand Facade opened."); - } + { + INFO (gui, "SessionCommand Facade opened."); + } diff --git a/src/proc/control/session-command-service.hpp b/src/proc/control/session-command-service.hpp index 9ca2faf93..f8522c114 100644 --- a/src/proc/control/session-command-service.hpp +++ b/src/proc/control/session-command-service.hpp @@ -46,7 +46,6 @@ #include "proc/control/command-dispatch.hpp" #include "proc/control/command-instance-manager.hpp" #include "common/instancehandle.hpp" -#include "lib/singleton-ref.hpp" #include "lib/diff/gen-node.hpp" #include "lib/nocopy.hpp" #include "lib/symbol.hpp" @@ -85,26 +84,23 @@ namespace control { CommandInstanceManager instanceManager_; + /* === Interface Lifecycle === */ + + using ServiceInstanceHandle = lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_SessionCommand, 0) + , SessionCommand + >; + ServiceInstanceHandle serviceInstance_; + + public: + SessionCommandService (CommandDispatch& dispatcherLoopInterface); + + /* === Implementation of the Facade Interface === */ Symbol cycle (Symbol cmdID, string const& invocationID) override; void trigger (Symbol cmdID, Rec const& args) override; void bindArg (Symbol cmdID, Rec const& args) override; void invoke (Symbol cmdID) override; - - - /* === Interface Lifecycle === */ - - typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_SessionCommand, 0) - , SessionCommand - > ServiceInstanceHandle; - - lib::SingletonRef implInstance_; - ServiceInstanceHandle serviceInstance_; - - public: - SessionCommandService (CommandDispatch& dispatcherLoopInterface); - }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 016499c03..225496b0d 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -28295,8 +28295,8 @@ - - + + @@ -28321,13 +28321,29 @@ - + + + + + + + + + + + + + + + + +