PIStateMachine::postEvent() now thread-safe and can be recursive
This commit is contained in:
@@ -45,11 +45,27 @@ public:
|
||||
template<typename... Args>
|
||||
bool postEvent(int event_id, Args... args) {
|
||||
if (!is_running) return false;
|
||||
if (in_post.exchange(true)) {
|
||||
PIMutexLocker ml(nested_mutex);
|
||||
nested_posts.enqueue([this, event_id, args...] { postEvent(event_id, args...); });
|
||||
// piCout << "queue nested post";
|
||||
return false;
|
||||
}
|
||||
need_finish = false;
|
||||
PIScopeExitCall exit_call([this] {
|
||||
in_post = false;
|
||||
if (need_finish) {
|
||||
is_running = false;
|
||||
if (on_finish) on_finish();
|
||||
} else {
|
||||
nested_mutex.lock();
|
||||
while (nested_posts.isNotEmpty()) {
|
||||
auto np = nested_posts.dequeue();
|
||||
nested_mutex.unlock();
|
||||
np();
|
||||
nested_mutex.lock();
|
||||
}
|
||||
nested_mutex.unlock();
|
||||
}
|
||||
});
|
||||
PIVector<PIStateBase *> active_states;
|
||||
@@ -71,6 +87,9 @@ private:
|
||||
void onFinish() override;
|
||||
|
||||
bool is_running = false, need_finish = false;
|
||||
PIQueue<std::function<void()>> nested_posts;
|
||||
PIMutex nested_mutex;
|
||||
std::atomic_bool in_post = {false};
|
||||
std::function<void()> on_finish;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user