Hi,
Did you consider adding build-in multi-thread support? (via policies maybe?)
I did. This is still work in progress (see https://github.com/boostorg/msm/blob/msm3/test/Lockfree1.cpp). There is a new lockfree_policy.
For example, I can guaranteed that all access to sub-fsm within its handlers (process_event()) will be synchronized. The problem is, sub-fsm "knows" about its parent and internally communicates with it (forwarding events etc). I can't control it from my side.
typical scenario: an action from sub-fsm
struct A_Init { template
void operator()(Evt&, FSM& fsm, SourceState&, TargetState&) const { std::thread([=]() mutable { std::lock_guardstd::mutex l(access); fsm.process_event(some_event()); }).detach(); } }; locking proccess_event() in sub-fsm doesn't help if it alters the root.
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. 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. 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. 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. HTH, Christophe