Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Master update hook vs callback queue #91

Merged
Merged
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
d9ff6ab
engine: run updateHook() only upon trigger or timeout
Mar 31, 2015
56cbddc
ports: restore default callback is trigger for event ports
Oct 22, 2014
c8a9b85
taskcontext: revert TriggerOnStart from property to attribute.
Apr 1, 2015
23d3a13
activity: fix slave activity in case no master or period is set
Apr 1, 2015
3b4087a
simulationactivity: also call work() after step().
Apr 1, 2015
77fca62
ports: process event port callbacks in all situations
Apr 1, 2015
45e44c1
tests: more tests for slave activities.
Apr 1, 2015
f1c8ebc
taskcore: count update/callback cycles
Apr 2, 2015
a626eb0
extras: added missing initializers to one of the FileDescriptorActivi…
meyerj Feb 9, 2015
1f1d68b
activity: cleanups + solve double stepping
Apr 2, 2015
06146b6
activity: implement abs/rel wait and overrun detection.
Apr 3, 2015
70ba5a3
engine: bail out early if message queue is empty
Apr 3, 2015
f266337
ports: use the message queue for port callbacks
Apr 3, 2015
047f92d
doc:add diagrams explaining the new/improved execution semantics
Apr 3, 2015
42a62e8
engine: remove support for child taskcontexts
Apr 3, 2015
d0f7919
scripting: remove cycle checking in sm scripts
Apr 13, 2015
58cb4bb
engine/activity: fixed blocking calls to ExecutionEngine::process()
meyerj Apr 13, 2015
8d53590
Merge pull request #3 from meyerj/master-update-hook-vs-callback-queue
Apr 13, 2015
d662010
scripting: use timeout() instead of trigger() when events arrive in a SM
psoetens Apr 30, 2015
719b781
Revert "ports: use the message queue for port callbacks"
meyerj Dec 16, 2015
0f71761
Moved portqueue from class TaskContext to the ExecutionEngine
meyerj Dec 16, 2015
431f81a
Fixed documentation
meyerj Dec 17, 2015
fdd405a
Removed obsolete prepareUpdateHook() method from class TaskCore
meyerj Dec 17, 2015
a0e3d89
Merge pull request #4 from meyerj/master-update-hook-vs-callback-queue
Jan 28, 2016
4f48698
extras: fixed missing work() call in SlaveActivity for the periodic case
meyerj Jan 29, 2016
4d750bd
Call Activity::step() from Activity::loop() for the non-periodic case…
meyerj Feb 2, 2016
71fe065
Merge pull request #6 from meyerj/master-update-hook-vs-callback-queue
Feb 2, 2016
7a8e488
engine: fixed forwarding of messages and port callbacks received in s…
meyerj Apr 5, 2016
603cd3e
engine: fixed regression from 7a8e48871e7b25301e942bbbd3cbdcc2cac35de…
meyerj Jun 6, 2016
cb4a376
slaveactivity: forward isPeriodic() member call to the master engine
meyerj Jun 6, 2016
e49cdf0
activity: fixed Activity::isPeriodic()
meyerj Jun 21, 2016
d04b1e9
Revert "slaveactivity: forward isPeriodic() member call to the master…
meyerj Nov 16, 2016
b9f2f34
Revert "engine/activity: fixed blocking calls to ExecutionEngine::pro…
meyerj Feb 16, 2017
92ea90a
activity: fix pure virtual function calls at thread termination after…
meyerj Apr 13, 2015
521f076
Merge pull request #9 from meyerj/master-update-hook-vs-callback-queu…
meyerj Feb 22, 2017
2503803
activity: fixed missing initializers for member variables introduced …
meyerj Oct 15, 2017
29cf65e
Merge remote-tracking branch 'origin/master' into master-update-hook-…
meyerj Oct 15, 2017
f067d2d
Clear the task's provided and required service interface during destr…
meyerj Feb 2, 2017
afe081a
tests: replace BOOST_ASSERT by BOOST_REQUIRE
meyerj Dec 8, 2017
171a700
activity: revert behavior for ORO_WAIT_REL policy to always wait for …
Dec 26, 2017
6047c60
activity: revert default wait policy to ORO_WAIT_ABS
Dec 26, 2017
3cd22a4
activity: use int member variable to store wait period policy and fix…
meyerj Jan 8, 2018
00caecb
tests: added unit test for wait period policy of Activity class
meyerj Jan 9, 2018
09f5543
Merge pull request #2 from Intermodalics/fix/activity_sleep_oro_wait_…
meyerj Jan 16, 2018
6e6c7aa
Merge branch 'master' into master-update-hook-vs-callback-queue
meyerj Apr 15, 2019
c28ad74
Merge branch 'master' into master-update-hook-vs-callback-queue
meyerj Apr 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
engine: remove support for child taskcontexts
This feature was ambiguous at best and not tested. It's
assumed now that a TaskCore always has an engine. We
still check for an activity, since in theory it may
not have one.

Signed-off-by: Peter Soetens <[email protected]>
Peter Soetens committed Apr 13, 2015

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 42a62e8d7b81cebcf9c34e012b339a302c200033
61 changes: 5 additions & 56 deletions rtt/ExecutionEngine.cpp
Original file line number Diff line number Diff line change
@@ -81,13 +81,6 @@ namespace RTT
{
Logger::In in("~ExecutionEngine");

// make a copy to avoid call-back troubles:
std::vector<TaskCore*> copy = children;
for (std::vector<TaskCore*>::iterator it = copy.begin(); it != copy.end();++it){
(*it)->setExecutionEngine( 0 );
}
assert( children.empty() );

ExecutableInterface* foo;
while ( f_queue->dequeue( foo ) )
foo->unloaded();
@@ -104,16 +97,6 @@ namespace RTT
return taskc;
}

void ExecutionEngine::addChild(TaskCore* tc) {
children.push_back( tc );
}

void ExecutionEngine::removeChild(TaskCore* tc) {
vector<TaskCore*>::iterator it = find (children.begin(), children.end(), tc );
if ( it != children.end() )
children.erase(it);
}

void ExecutionEngine::processFunctions()
{
// Execute all loaded Functions :
@@ -135,7 +118,7 @@ namespace RTT

bool ExecutionEngine::runFunction( ExecutableInterface* f )
{
if (this->getActivity() && f) {
if ( f && this->getActivity() ) {
// We only reject running functions when we're in the FatalError state.
if (taskc && taskc->mTaskState == TaskCore::FatalError )
return false;
@@ -171,7 +154,7 @@ namespace RTT
return true;

// When not running, just remove.
if ( getActivity() == 0 || !this->getActivity()->isActive() ) {
if ( !this->getActivity()->isActive() ) {
if ( removeSelfFunction( f ) == false )
return false;
} else {
@@ -207,7 +190,6 @@ namespace RTT
}

bool ExecutionEngine::initialize() {
// nop
return true;
}

@@ -378,10 +360,10 @@ namespace RTT
/* Update step */
processMessages();
processFunctions();
processChildren();
processHooks();
}
}
void ExecutionEngine::processChildren() {
void ExecutionEngine::processHooks() {
// only call updateHook in the Running state.
if ( taskc ) {
// A trigger() in startHook() will be ignored, we trigger in TaskCore after startHook finishes.
@@ -411,53 +393,20 @@ namespace RTT
)
}
}
if ( !this->getActivity() || ! this->getActivity()->isRunning() ) return;

// call all children as well.
for (std::vector<TaskCore*>::iterator it = children.begin(); it != children.end();++it) {
if ( (*it)->mTaskState == TaskCore::Running && (*it)->mTargetState == TaskCore::Running ){
TRY (
(*it)->updateHook();
) CATCH(std::exception const& e,
log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
log(Error) << " " << e.what() << endlog();
(*it)->exception();
) CATCH_ALL (
log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
(*it)->exception(); // calls stopHook,cleanupHook
)
}
if ( (*it)->mTaskState == TaskCore::RunTimeError ){
TRY (
(*it)->errorHook();
) CATCH(std::exception const& e,
log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
log(Error) << " " << e.what() << endlog();
(*it)->exception();
) CATCH_ALL (
log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
(*it)->exception(); // calls stopHook,cleanupHook
)
}
if ( !this->getActivity() || ! this->getActivity()->isRunning() ) return;
}
}

bool ExecutionEngine::breakLoop() {
bool ok = true;
if (taskc)
ok = taskc->breakUpdateHook();
for (std::vector<TaskCore*>::iterator it = children.begin(); it != children.end();++it) {
ok = (*it)->breakUpdateHook() && ok;
}
return ok;
}

bool ExecutionEngine::stopTask(TaskCore* task) {
// stop and start where former will call breakLoop() in case of non-periodic.
// this is a forced synchronization point, since stop() will only return when
// step() returned.
if ( getActivity() && this->getActivity()->stop() ) {
if ( this->getActivity() && this->getActivity()->stop() ) {
this->getActivity()->start();
return true;
}
26 changes: 4 additions & 22 deletions rtt/ExecutionEngine.hpp
Original file line number Diff line number Diff line change
@@ -59,19 +59,11 @@ namespace RTT
/**
* An execution engine serialises (executes one after the other)
* the execution of all commands, programs, state machines and
* incomming events for a task. Any function executing in the
* incoming events for a task. Any function executing in the
* same execution engine is guaranteed to be thread-safe with
* respect to other functions executing in the same execution
* engine.
*
* The ExecutionEngine bundles a internal::CommandProcessor, scripting::ProgramProcessor,
* scripting::StateMachineProcessor and MessageProcessor.
*
* @par Changing the Execution Policy
* One can subclass this class in order to change the run-time
* behaviour. Use base::TaskCore::setExecutionEngine in order to
* install a new ExecutionEngine in a component. All Members of
* this class are protected and thus accessible in a subclass.
* @ingroup Processor
*/
class RTT_API ExecutionEngine
@@ -90,21 +82,13 @@ namespace RTT

/**
* The base::TaskCore which created this ExecutionEngine.
* Identical to getTaskCore().
*/
base::TaskCore* getParent();

/**
* Add a base::TaskCore to execute.
*/
virtual void addChild(base::TaskCore* tc);

/**
* Remove a base::TaskCore from execution.
*/
virtual void removeChild(base::TaskCore* tc);

/**
* Returns the owner of this execution engine.
* Identical to getParent().
*/
base::TaskCore* getTaskCore() const { return taskc; }

@@ -253,8 +237,6 @@ namespace RTT
*/
internal::MWSRQueue<base::DisposableInterface*>* mqueue;

std::vector<base::TaskCore*> children;

/**
* Stores all functions we're executing.
*/
@@ -271,7 +253,7 @@ namespace RTT

void processMessages();
void processFunctions();
void processChildren();
void processHooks();

virtual bool initialize();

19 changes: 5 additions & 14 deletions rtt/TaskContext.cpp
Original file line number Diff line number Diff line change
@@ -79,18 +79,6 @@ namespace RTT
this->setup();
}

TaskContext::TaskContext(const std::string& name, ExecutionEngine* parent, TaskState initial_state /*= Stopped*/ )
: TaskCore(parent, initial_state)
,tcservice(new Service(name,this) ), tcrequests( new ServiceRequester(name,this) )
#if defined(ORO_ACT_DEFAULT_SEQUENTIAL)
,our_act( parent ? 0 : new SequentialActivity( this->engine() ) )
#elif defined(ORO_ACT_DEFAULT_ACTIVITY)
,our_act( parent ? 0 : new Activity( this->engine(), name ) )
#endif
{
this->setup();
}

void TaskContext::setup()
{
tcservice->setOwner(this);
@@ -136,9 +124,11 @@ namespace RTT
// here would only lead to calling invalid virtual functions.
// [Rule no 1: Don't call virtual functions in a destructor.]
// [Rule no 2: Don't call virtual functions in a constructor.]
tcservice->clear();

tcrequests->clear();
// these need to be freed before we cleanup the EE:
localservs.clear();
tcservice.reset();
tcrequests.reset();

// remove from all users.
while( !musers.empty() ) {
@@ -356,6 +346,7 @@ namespace RTT
new_act->stop();
if(our_act){
our_act->stop();
our_act.reset();
}
new_act->run( this->engine() );
our_act = ActivityInterface::shared_ptr( new_act );
11 changes: 0 additions & 11 deletions rtt/TaskContext.hpp
Original file line number Diff line number Diff line change
@@ -109,17 +109,6 @@ namespace RTT
*/
TaskContext( const std::string& name, TaskState initial_state = Stopped );

/**
* Create a TaskContext.
* Its commands programs and state machines are processed by \a parent.
* Use this constructor to share execution engines among task contexts, such that
* the execution of their functionality is serialised (executed in the same thread).
* @param name The name of this component.
* @param initial_state Provide the \a PreOperational parameter flag here
* to force users in calling configure(), before they call start().
*/
TaskContext(const std::string& name, ExecutionEngine* parent, TaskState initial_state = Stopped );

virtual ~TaskContext();

/**
18 changes: 9 additions & 9 deletions rtt/base/CoreRunnableInterface.cpp
Original file line number Diff line number Diff line change
@@ -45,17 +45,17 @@ namespace RTT {
using namespace base;

RunnableInterface::~RunnableInterface() {
if ( this->owner_task && this->owner_task->isRunning() ) {
if ( this->owner_act && this->owner_act->isRunning() ) {
Logger::In in("~RunnableInterface()");
log(Critical)
<<"Activity still running, but RunnableInterface destroyed! Stop the task"
" before deleting this object. Crash may be imminent."<<endlog();
}
if ( this->owner_task )
this->owner_task->disableRun(this);
if ( this->owner_act )
this->owner_act->disableRun(this);
}

RunnableInterface::RunnableInterface() : owner_task(0) {}
RunnableInterface::RunnableInterface() : owner_act(0) {}

void RunnableInterface::loop() {
this->step();
@@ -71,17 +71,17 @@ namespace RTT {
void RunnableInterface::work(WorkReason reason) {}

void RunnableInterface::setActivity( ActivityInterface* task ) {
if (owner_task) {
if (owner_act) {
// notify old owner he's out.
owner_task->disableRun(this);
owner_act->disableRun(this);
}

owner_task = task;
owner_act = task;
}

os::ThreadInterface* RunnableInterface::getThread() const {
if (owner_task)
return owner_task->thread();
if (owner_act)
return owner_act->thread();
return 0;
}

4 changes: 2 additions & 2 deletions rtt/base/RunnableInterface.hpp
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ namespace RTT
/**
* The Activityobject which owns this RunnableInterface.
*/
ActivityInterface* owner_task;
ActivityInterface* owner_act;
public:
enum WorkReason { TimeOut = 0, Trigger, IOReady };
/**
@@ -172,7 +172,7 @@ namespace RTT
};


ActivityInterface* RunnableInterface::getActivity() const { return owner_task; }
ActivityInterface* RunnableInterface::getActivity() const { return owner_act; }
}}

#endif
Loading