Boost logo

Boost Users :

Subject: Re: [Boost-users] [msm] multi thread access
From: christophe.j.henry_at_[hidden]
Date: 2015-02-05 01:43:02


>> Actually your example is probably wrong (it's my worst design decision)
>> because the fsm parameter in an action of a submachine itself is the
>> submachine, not the outer. But yes, if you have a pseudo exit then you
>> will call the outer from the sub fsm.
>
>That's my case.
>Another thread triggers the sub-fsm to move the exit state.

In the meantime I did a bit more and implemented your use case (if I
understood it correctly) in the msm3 branch and added a test
(https://github.com/boostorg/msm/blob/msm3/test/LockfreeMessageQueue.cpp).
I did not try it out with composite states though.

>> I unsure of what your problem is, you could have your mutex in the outer
>> and it would work. The sub fsm would lock the whole fsm, then call
>> process_event, which runs to completion, done.
>
>Unfortunately, there is no "a natural way" for subs to have access to the
>root...

True. As I said, it was a mistake, one I want to correct in msm3.

>Now I use implementation that recursively goes through the states, but
>still it is ugly and has restrictions.

The "standard" way is usually to have the outer fsm give a pointer or
boost::function to the sub. Not exactly beautiful but at least faster and
slightly less ugly.

>> Normally, MSM is not thread-safe if that's what you mean...
>>
>> Clearly, locking such a long time is still undesirable, which is why I
>> went lockfree. Your actions run at the same time as the active state
>> switching. It's really fast, but quite hard to debug and understand. For
>> example, I am quite sure my implementation works for simple fsms, for
>> internal transitions, for orthogonal regions, soon for deferred events
>> and event queue, but my test for submachines does not and I still did
>> not figure out if the code or the test is wrong...
>>
>> If you want to try it out, I'm interested in your experience.
>
>I'll take a look to msm3
>Do you have a roadmap for v3?

No. At the moment I do it as low prio because most of my free time goes to
my new library, asynchronous.
I hope to make some progress on msm3 this year, little by little.

>> Otherwise, it's all I have at the moment, I had no time to push it
>> further yet. My priority at the moment goes to finishing the upcoming
>> asynchronous, which solves this problem nicely (we use it at work for
>> quite some time now) by taking care of enqueing calls between threads. I
>> run my fsms in a single thread, avoiding concurrency on the state
>> machine.
>>
>
>What is "asynchronous"?
>Looking through recent subjects does reveal nothing.

Oh, sorry. I made some talks at CppNow! and Meeting C++ last year but did
not talk on this list about it yet.
You can find the doc at: https://github.com/henry-ch/asynchronous .
I think for your use case it might be pretty much what you want. I wanted to
do this since I started msm. We now use it heavily at work so it's also good
tested. In your case, you'd make a Servant, which would hold your fsm and
live in a thread (along with potentially many more). Then your other threads
would only get a thread-safe Proxy to it and call the proxy members (say,
process_event). The Proxy would enqueue the call into the queue of the
thread where your fsm lives, keeping it safe.
The library has much more but I hope you get the idea.

>I wanna ask another thing.
>As I see currently sub-fsms work as unconditional jump when returning.
>
>Consider I have a fsm "Foo" with a generic code that isolated to a sub-fsm
>"Bar"
>
>At the transition form Bar's exit point to Foo I don't know about the
>original state that calls Bar
>
>So, if Bar uses more the one time, I have to invent extra conditional/flags
>etc to make a decision what state to move.
>
>Foo's transition table:
>
>// Start Event Next Action, Guard
>// +--------+---------+--------+---------+--------+
>Row < State1, evt1, Bar, none, none >,
>Row < State2, evt2, Bar, none, none >,
>// +--------+---------+--------+---------+--------+
>Row < Bar::Exit, none, State1, none, ??? >,
>Row < Bar::Exit, none, State2, none, ??? >
>// +--------+---------+--------+---------+--------+
>
>It would be nice, if the sub-fsm remembers the source state from the outer
>that causes call. That state can be used in guard.

Hmm I did not think about this. I need to think about it, maybe some kind of
history would do. Normally, I would solve this by entering Bar with an event
containing this information, saving it in Bar, then exiting Bar with another
event than none, holding this same information back, so it would be usable
in a guard.

HTH,
Christophe


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net