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
This commit is contained in:
Fischlurch 2018-04-02 04:19:17 +02:00
parent be789bea59
commit 29ee5131f4
6 changed files with 89 additions and 39 deletions

View file

@ -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<class IMP>
template<class IMP =SRV>
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<IMP>();
}
~ServiceInstance()
{
deactivateServiceAccess();
shutdown();
}
template<typename...ARGS>
IMP&
createInstance(ARGS&& ...ctorArgs)
{
instance_.reset (new IMP(forward<ARGS> (ctorArgs)...));
activateServiceAccess (*instance_);
return *instance_;
}
void
shutdown() noexcept
{
if (instance_)
{
deactivateServiceAccess();
instance_.reset();
}
}
explicit
operator bool() const
{

View file

@ -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);
}
};

View file

@ -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 <memory>
@ -116,9 +117,10 @@ namespace control {
, public CommandDispatch
, public Sync<RecursiveLock_Waitable>
{
using ServiceHandle = lib::DependInject<SessionCommandService>::ServiceInstance<>;
/** manage the primary public Session interface */
unique_ptr<SessionCommandService> 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();
}

View file

@ -189,9 +189,8 @@ namespace control {
using lumiera::facade::LUMIERA_ERROR_FACADE_LIFECYCLE;
typedef lib::SingletonRef<SessionCommand>::Accessor InstanceRef;
InstanceRef _instance; ///< a backdoor for the C Language impl to access the actual SessionCommand implementation...
lib::Depend<SessionCommandService> _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<Rec const *> (args));
_instance().trigger(cmdID, *static_cast<Rec const *> (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<Rec const *> (args));
_instance().bindArg(cmdID, *static_cast<Rec const *> (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.");
}

View file

@ -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<SessionCommand> implInstance_;
ServiceInstanceHandle serviceInstance_;
public:
SessionCommandService (CommandDispatch& dispatcherLoopInterface);
};

View file

@ -28295,8 +28295,8 @@
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521858774321" ID="ID_302686020" MODIFIED="1521858778744" TEXT="aufr&#xe4;umen">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521858774321" ID="ID_302686020" MODIFIED="1522635466053" TEXT="aufr&#xe4;umen">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1521858779614" ID="ID_62114860" MODIFIED="1521928808594" TEXT="was ist depend4test?">
<icon BUILTIN="help"/>
<node CREATED="1521928764171" ID="ID_507085354" MODIFIED="1521928798462" TEXT="die alte Testmock-L&#xf6;sung">
@ -28321,13 +28321,29 @@
<node CREATED="1521928963447" ID="ID_1493572426" MODIFIED="1521929015463" TEXT="ziemlich eng mit den Interface-Proxies verbandelt">
<icon BUILTIN="messagebox_warning"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521928978853" ID="ID_47671209" MODIFIED="1521929006930" TEXT="diese sollten auf Depend umgestellt werden">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521928978853" ID="ID_47671209" MODIFIED="1522635461892" TEXT="diese sollten auf Depend umgestellt werden">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1522635397309" ID="ID_1630981728" MODIFIED="1522635457722" TEXT="SessionCommandService">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522635417932" ID="ID_826517015" MODIFIED="1522635454403" TEXT="DisplayService">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522635433910" ID="ID_578198662" MODIFIED="1522635455354" TEXT="GuiNotification">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522635450269" ID="ID_609069219" MODIFIED="1522635455898" TEXT="DummyPlayerService">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521929007449" ID="ID_451474924" MODIFIED="1521929011482" TEXT="danach kann es weg">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522635350488" ID="ID_1673980887" MODIFIED="1522635365465" TEXT="InterfaceProxy auch umstellen?">
<icon BUILTIN="help"/>
<node CREATED="1522635366958" ID="ID_70940233" MODIFIED="1522635375297" TEXT="w&#xe4;re jetzt ebenfalls denkbar"/>
</node>
</node>
<node COLOR="#338800" CREATED="1522033564057" ID="ID_1294295502" MODIFIED="1522632239961" TEXT="Nacharbeiten">
<icon BUILTIN="button_ok"/>