Breaking out of NonPeriodic activites

We want to be able to break out of blocking, non-periodic activites in both the TaskBrowser and Deployer. These two links don't quite answer our question:

http://orocos.org/node/653

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=418

Is the attached about the simplest way to do this? To derive a new activity that knows the component of interest, and calls the equivalent of "breakLoop()" on the component.

TIA
Stephen

AttachmentSize
testQuittingNonPeriodicComponents.cpp1.67 KB

Breaking out of NonPeriodic activites

On Tue, Jun 23, 2009 at 03:35, <kiwi [dot] net [..] ...> wrote:
> We want to be able to break out of blocking, non-periodic activites in both the TaskBrowser and Deployer. These two links don't quite answer our question:
>
> http://orocos.org/node/653
>
> https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=418
>
> Is the attached about the simplest way to do this? To derive a new activity that knows the component of interest, and calls the equivalent of "breakLoop()" on the component.

(there seems to be a problem with posts from the forum, the attachment
is missing and the ML post returned back as a reply to the forum, See
http://orocos.org/forum/website-talk/forum-vs-mail-manager-bug for
discussion, original forum post is here:
http://www.orocos.org/forum/orocos/orocos-users/breaking-out-nonperiodic...
)

The way you do it is possible, but that component won't be able to
process commands or events. Why doesn't trigger() work for you ?

Peter

Breaking out of NonPeriodic activites

On Jun 23, 2009, at 05:27 , Peter Soetens wrote:

> On Tue, Jun 23, 2009 at 03:35, <kiwi [dot] net [..] ...> wrote:
>> We want to be able to break out of blocking, non-periodic activites
>> in both the TaskBrowser and Deployer. These two links don't quite
>> answer our question:
>>
>> http://orocos.org/node/653
>>
>> https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=418
>>
>> Is the attached about the simplest way to do this? To derive a new
>> activity that knows the component of interest, and calls the
>> equivalent of "breakLoop()" on the component.
>
> (there seems to be a problem with posts from the forum, the attachment
> is missing and the ML post returned back as a reply to the forum, See
> http://orocos.org/forum/website-talk/forum-vs-mail-manager-bug for
> discussion, original forum post is here:
> http://www.orocos.org/forum/orocos/orocos-users/breaking-out-nonperiodic...
> )

Interesting, as the attachment was there last night when I created the
post. I explicitly pulled the file back to look at it.

> The way you do it is possible, but that component won't be able to
> process commands or events. Why doesn't trigger() work for you ?

How does trigger() come in to it? Are you saying that the overall
structure of our non-periodic component should be reworked? Yes, I
realise that never returning from updateHook() prevents use of
commands and events, but I don't really see a straight-forward way to
incorporate that alongside blocking calls that take non-determinstic
amounts of time. Am I missing something?

The documentation is very confusing as to where the breakLoop() goes,
so this was our best guess. Tracking through all the classes following
breakLoop()'s didn't really help ...

All we want is typing "quit" in the taskBrowser eventually calls some
kind of breakLoop-like function in the component, which can arrange
for the blocking call (whatever it might be) to end.

Cheers
Stephen

Breaking out of NonPeriodic activites

On Tue, Jun 23, 2009 at 13:42, Stephen Roderick<kiwi [dot] net [..] ...> wrote:
> On Jun 23, 2009, at 05:27 , Peter Soetens wrote:
>
>> On Tue, Jun 23, 2009 at 03:35, <kiwi [dot] net [..] ...> wrote:
>>>
>>> We want to be able to break out of blocking, non-periodic activites in
>>> both the TaskBrowser and Deployer. These two links don't quite answer our
>>> question:
>>>
>>> http://orocos.org/node/653
>>>
>>> https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=418
>>>
>>> Is the attached about the simplest way to do this? To derive a new
>>> activity that knows the component of interest, and calls the equivalent of
>>> "breakLoop()" on the component.
>>
>> (there seems to be a problem with posts from the forum, the attachment
>> is missing and the ML post returned back as a reply to the forum, See
>> http://orocos.org/forum/website-talk/forum-vs-mail-manager-bug for
>> discussion, original forum post is here:
>>
>> http://www.orocos.org/forum/orocos/orocos-users/breaking-out-nonperiodic...
>> )
>
> Interesting, as the attachment was there last night when I created the post.
> I explicitly pulled the file back to look at it.
>
>> The way you do it is possible, but that component won't be able to
>> process commands or events. Why doesn't trigger() work for you ?
>
> How does trigger() come in to it? Are you saying that the overall structure
> of our non-periodic component should be reworked? Yes, I realise that never
> returning from updateHook() prevents use of commands and events, but I don't
> really see a straight-forward way to incorporate that alongside blocking
> calls that take non-determinstic amounts of time. Am I missing something?

There are only two ways of breaking out of a function with unbounded
time, a. by specifying a timeout or b. by forcing it to return using a
signal or another function call. The trigger() method only works for
case a., It assumes your block() function will return after some time
control, such that commands, events or plain stopping can be handled.
If your updateHook is of case b., only a breakLoop() like solution can
work, which signals the block() function to return. It's probably a
flaw that we don't have 'breakUpdateHook()' in the TC. Even worse, the
EE implements 'breakLoop()' to return true.

The new 'Thread' and 'SingleThread' implementations put a timeout
(remember the discussion...) on stop(), which will force the thread to
be killed when the application exits. We don't want to rely on that as
a default behaviour.

>
> The documentation is very confusing as to where the breakLoop() goes, so
> this was our best guess. Tracking through all the classes following
> breakLoop()'s didn't really help ...
>
> All we want is typing "quit" in the taskBrowser eventually calls some kind
> of breakLoop-like function in the component, which can arrange for the
> blocking call (whatever it might be) to end.

I agree. See the patch in attachment. This can break current blocking
updateHook() functions that assume that stop() will wait long enough
for updateHook() to return. With this patch, the breakUpdateHook()
returns false, meaning 'I can't interrupt updateHook(), abort the
stop().' Such components would need to add 'bool breakUpdateHook() {
return true; }' to their component.

Thoughts ?

Peter

Breaking out of NonPeriodic activites

On Jun 23, 2009, at 09:16 , Peter Soetens wrote:

> On Tue, Jun 23, 2009 at 13:42, Stephen Roderick<kiwi [dot] net [..] ...>
> wrote:
>> On Jun 23, 2009, at 05:27 , Peter Soetens wrote:
>>
>>> On Tue, Jun 23, 2009 at 03:35, <kiwi [dot] net [..] ...> wrote:
>>>>
>>>> We want to be able to break out of blocking, non-periodic
>>>> activites in
>>>> both the TaskBrowser and Deployer. These two links don't quite
>>>> answer our
>>>> question:
>>>>
>>>> http://orocos.org/node/653
>>>>
>>>> https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=418
>>>>
>>>> Is the attached about the simplest way to do this? To derive a new
>>>> activity that knows the component of interest, and calls the
>>>> equivalent of
>>>> "breakLoop()" on the component.
>>>
>>> (there seems to be a problem with posts from the forum, the
>>> attachment
>>> is missing and the ML post returned back as a reply to the forum,
>>> See
>>> http://orocos.org/forum/website-talk/forum-vs-mail-manager-bug for
>>> discussion, original forum post is here:
>>>
>>> http://www.orocos.org/forum/orocos/orocos-users/breaking-out-nonperiodic...
>>> )
>>
>
<snip>

>> The documentation is very confusing as to where the breakLoop()
>> goes, so
>> this was our best guess. Tracking through all the classes following
>> breakLoop()'s didn't really help ...
>>
>> All we want is typing "quit" in the taskBrowser eventually calls
>> some kind
>> of breakLoop-like function in the component, which can arrange for
>> the
>> blocking call (whatever it might be) to end.
>
> I agree. See the patch in attachment. This can break current blocking
> updateHook() functions that assume that stop() will wait long enough
> for updateHook() to return. With this patch, the breakUpdateHook()
> returns false, meaning 'I can't interrupt updateHook(), abort the
> stop().' Such components would need to add 'bool breakUpdateHook() {
> return true; }' to their component.
>
> Thoughts ?

Patch works great. Will this make it into v1.8 or v2.0?

Many thanks
Stephen

Breaking out of NonPeriodic activites

On Jun 23, 2009, at 09:16 , Peter Soetens wrote:

> On Tue, Jun 23, 2009 at 13:42, Stephen Roderick<kiwi [dot] net [..] ...>
> wrote:
>> On Jun 23, 2009, at 05:27 , Peter Soetens wrote:
>>
>>> On Tue, Jun 23, 2009 at 03:35, <kiwi [dot] net [..] ...> wrote:
>>>>
>>>> We want to be able to break out of blocking, non-periodic
>>>> activites in
>>>> both the TaskBrowser and Deployer. These two links don't quite
>>>> answer our
>>>> question:
>>>>
>>>> http://orocos.org/node/653
>>>>
>>>> https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=418
>>>>
>>>> Is the attached about the simplest way to do this? To derive a new
>>>> activity that knows the component of interest, and calls the
>>>> equivalent of
>>>> "breakLoop()" on the component.
>>>
>>> (there seems to be a problem with posts from the forum, the
>>> attachment
>>> is missing and the ML post returned back as a reply to the forum,
>>> See
>>> http://orocos.org/forum/website-talk/forum-vs-mail-manager-bug for
>>> discussion, original forum post is here:
>>>
>>> http://www.orocos.org/forum/orocos/orocos-users/breaking-out-nonperiodic...
>>> )
>>
>> Interesting, as the attachment was there last night when I created
>> the post.
>> I explicitly pulled the file back to look at it.
>>
>>> The way you do it is possible, but that component won't be able to
>>> process commands or events. Why doesn't trigger() work for you ?
>>
>> How does trigger() come in to it? Are you saying that the overall
>> structure
>> of our non-periodic component should be reworked? Yes, I realise
>> that never
>> returning from updateHook() prevents use of commands and events,
>> but I don't
>> really see a straight-forward way to incorporate that alongside
>> blocking
>> calls that take non-determinstic amounts of time. Am I missing
>> something?
>
> There are only two ways of breaking out of a function with unbounded
> time, a. by specifying a timeout or b. by forcing it to return using a
> signal or another function call. The trigger() method only works for
> case a., It assumes your block() function will return after some time
> control, such that commands, events or plain stopping can be handled.
> If your updateHook is of case b., only a breakLoop() like solution can
> work, which signals the block() function to return. It's probably a
> flaw that we don't have 'breakUpdateHook()' in the TC. Even worse, the
> EE implements 'breakLoop()' to return true.
>
> The new 'Thread' and 'SingleThread' implementations put a timeout
> (remember the discussion...) on stop(), which will force the thread to
> be killed when the application exits. We don't want to rely on that as
> a default behaviour.

Agreed. Useful behaviour, but not useful as a default (particularly
for newbies)

>> The documentation is very confusing as to where the breakLoop()
>> goes, so
>> this was our best guess. Tracking through all the classes following
>> breakLoop()'s didn't really help ...
>>
>> All we want is typing "quit" in the taskBrowser eventually calls
>> some kind
>> of breakLoop-like function in the component, which can arrange for
>> the
>> blocking call (whatever it might be) to end.
>
> I agree. See the patch in attachment. This can break current blocking
> updateHook() functions that assume that stop() will wait long enough
> for updateHook() to return. With this patch, the breakUpdateHook()
> returns false, meaning 'I can't interrupt updateHook(), abort the
> stop().' Such components would need to add 'bool breakUpdateHook() {
> return true; }' to their component.

Ahhh ... this is what we *thought* that breakLoop() was supposed to
do! :-)

Personally I think the above is fairly natural for blocking
components, and matches what most people write when they do it with
threads/mutexes. Some kind of function "calls" into the thread and
instructs its blocking loop to quit. If it doesn't quit, then you
forcibly kill the thread.

So how on earth is breakLoop() supposed to be used then? Were non-
periodic activities designed to be used such that updateHook()
returned occasionally, allowing external items to affect the component
(eg events, commands)? Even then, I am not sure how breakLoop() really
enters the situation, as it only works in the activity and not within
the component. Or does the activity just try to "stop" the
component ...?

Were you expecting people to write blocking, non-periodic components
something like the following?
&#10;startHook()&#10;     open socket&#10;&#10;stopHook()&#10;     close socket&#10;&#10;updateHook()&#10;     read from socket, with timeout&#10;     engine()-&gt;trigger()&#10;
If so, what are the timing considerations between calling trigger()
and the next call to updateHook()? Ignoring other components taking
CPU time, is it just that whatever events/commands/statemachine-
processing that need to be done are done, and then updateHook() is
immediately called again?

Many thanks, will try this patch later today.
S

Breaking out of NonPeriodic activites

On Tue, Jun 23, 2009 at 15:35, Stephen Roderick<kiwi [dot] net [..] ...> wrote:
>>> The documentation is very confusing as to where the breakLoop() goes, so
>>> this was our best guess. Tracking through all the classes following
>>> breakLoop()'s didn't really help ...
>>>
>>> All we want is typing "quit" in the taskBrowser eventually calls some
>>> kind
>>> of breakLoop-like function in the component, which can arrange for the
>>> blocking call (whatever it might be) to end.
>>
>> I agree. See the patch in attachment. This can break current blocking
>> updateHook() functions that assume that stop() will wait long enough
>> for updateHook() to return. With this patch, the breakUpdateHook()
>> returns  false, meaning 'I can't interrupt updateHook(), abort the
>> stop().' Such components would need to add 'bool breakUpdateHook() {
>> return true; }' to their component.
>
> Ahhh ... this is what we *thought* that breakLoop() was supposed to do! :-)
>
> Personally I think the above is fairly natural for blocking components, and
> matches what most people write when they do it with threads/mutexes. Some
> kind of function "calls" into the thread and instructs its blocking loop to
> quit. If it doesn't quit, then you forcibly kill the thread.

I agree.

>
> So how on earth is breakLoop() supposed to be used then? Were non-periodic
> activities designed to be used such that updateHook() returned occasionally,
> allowing external items to affect the component (eg events, commands)? Even
> then, I am not sure how breakLoop() really enters the situation, as it only
> works in the activity and not within the component. Or does the activity
> just try to "stop" the component ...?

Well, if breakLoop() returns true (which the EE always did, on behalf
of the component), stop() blocks until updateHook() returns. When
updateHook() returns, stop() then calls stopHook().

>
> Were you expecting people to write blocking, non-periodic components
> something like the following?
> &#10;&gt; startHook()&#10;&gt;    open socket&#10;&gt;&#10;&gt; stopHook()&#10;&gt;    close socket&#10;&gt;&#10;&gt; updateHook()&#10;&gt;    read from socket, with timeout&#10;&gt;    engine()-&gt;trigger()&#10;&gt;

Yes that was the example we had in mind, because you are very likely
to be interested in incoming commands/events/stop. In this reasoning,
breakUpdateHook() is optional/unnecessary. But on the other hand, it's
awkward to have a whole breakLoop() mechanism hidden in such a way
that it boils down to not being usable by the end user.

> If so, what are the timing considerations between calling trigger() and the
> next call to updateHook()?

That's equal as using a while(1) loop (walking up the stack,
updateHook is eventually executed in a while(1) loop).

> Ignoring other components taking CPU time, is it
> just that whatever events/commands/statemachine-processing that need to be
> done are done, and then updateHook() is immediately called again?

Yes. We shortly unlock/relock a mutex and the same happens with a
semaphore (raise->lower). A real-time scheduler will not schedule you
away in this scenario.

Peter

Breaking out of NonPeriodic activites

We want to be able to break out of blocking, non-periodic activites in both the TaskBrowser and Deployer. These two links don't quite answer our question:

http://orocos.org/node/653

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=418

Is the attached about the simplest way to do this? To derive a new activity that knows the component of interest, and calls the equivalent of "breakLoop()" on the component.

TIA
Stephen