Next: Integrating Scheme Code, Previous: Foreign Component, Up: Code Integration [Contents][Index]
A Dezyne Thread-safe Shell guarantees safe use of a Dezyne system
component in a multi-threaded environment. It also implements the use
of the blocking
and the defer
keywords.
Use the dzn command-line client to generate code and a thread-safe shell:
dzn code -l c++ -s SYSTEM FILE (1)
Explanation:
1) Generates code for all components and interfaces referred to in the SYSTEM component. In addition a thread-safe shell is generated for SYSTEM.
A thread-safe shell wraps a Dezyne system component. In addition to an instance of the Dezyne component it contains a thread and an event queue. External code can call event functions on system ports. The thread-safe shell defers each external call by posting a function object in the event queue. A thread private to the thread-safe shell takes deferred functions from the queue and executes them one by one. Thus, external calls are serviced in the order of arrival.
An external call of a provides port in event blocks until the
thread-safe shell private thread has completed the deferred function
call. The external call blocks until a reply
has been executed
for the input event port. A subsequent call on a blocked port will block
until the prior call returns.
An external call of a requires port out event returns a soon as the event call is scheduled. The external call return is not synchronized with the actual execution of the event by a thread-safe shell private thread.
Generating C++ code with a thread-safe shell for component SYS
results in files: SYS.hh
, SYS.cc
, BHV.hh
and
IA.hh
.
A call of SYS::pp.in.iv()
captures input parameters by value to
prevent data races. The call schedules a call to
SYS::bhv.pp.in.iv()
and blocks the calling thread until the
scheduled call returns.
A call of SYS::rp.out.o()
captures input parameters by value to
prevent data races. The call schedules a call to
SYS::bhv.rp.out.o()
and returns immediately.
component SYS { provides IA pp; requires IA rp; system { BHV bhv; pp <=> bhv.pp; bhv.rp <=> rp; } } component BHV { provides IA pp; requires IA rp; } extern int $int$; interface IA { in void iv(int i); out void o(int i); behavior { on iv: {} on optional: o; } }
File SYS.hh:
#ifndef SYS_HH #define SYS_HH #include #include #include #include #include "BHV.hh" #include "IA.hh" #include "IA.hh" namespace dzn {struct locator;} struct SYS { dzn::meta dzn_meta; dzn::runtime dzn_runtime; dzn::locator dzn_locator; BHV bhv; IA pp; IA rp; dzn::pump dzn_pump; SYS (dzn::locator const&); }; #endif // SYS_HH
File SYS.cc:
#include "SYS.hh" SYS::SYS (dzn::locator const& locator) : dzn_meta{"","SYS",0,{&bhv.dzn_meta},{}} , dzn_locator (locator.clone ().set (dzn_runtime).set (dzn_pump)) , bhv(dzn_locator) , pp (bhv.pp) , rp (bhv.rp) , dzn_pump () { pp.in.iv = [&] (int i) { return dzn::shell (dzn_pump, [&,i] {return bhv.pp.in.iv (i);}); }; rp.out.o = [&] (int i) { return dzn_pump ([&,i] {return bhv.rp.out.o (i);}); }; bhv.pp.out.o = std::ref (pp.out.o); bhv.rp.in.iv = std::ref (rp.in.iv); bhv.dzn_meta.parent = &dzn_meta; bhv.dzn_meta.name = "bhv"; }
Next: Integrating Scheme Code, Previous: Foreign Component, Up: Code Integration [Contents][Index]