PIStateMachine::postEvent() now thread-safe and can be recursive
This commit is contained in:
@@ -45,11 +45,27 @@ public:
|
|||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
bool postEvent(int event_id, Args... args) {
|
bool postEvent(int event_id, Args... args) {
|
||||||
if (!is_running) return false;
|
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;
|
need_finish = false;
|
||||||
PIScopeExitCall exit_call([this] {
|
PIScopeExitCall exit_call([this] {
|
||||||
|
in_post = false;
|
||||||
if (need_finish) {
|
if (need_finish) {
|
||||||
is_running = false;
|
is_running = false;
|
||||||
if (on_finish) on_finish();
|
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;
|
PIVector<PIStateBase *> active_states;
|
||||||
@@ -71,6 +87,9 @@ private:
|
|||||||
void onFinish() override;
|
void onFinish() override;
|
||||||
|
|
||||||
bool is_running = false, need_finish = false;
|
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;
|
std::function<void()> on_finish;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
33
main.cpp
33
main.cpp
@@ -28,7 +28,7 @@ void tfunc4(int delim) {
|
|||||||
|
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
PIPackedTCP * tcp_s =
|
/*PIPackedTCP * tcp_s =
|
||||||
PIIODevice::createFromFullPath("ptcp://s::8000")->cast<PIPackedTCP>(); // new PIPackedTCP(PIPackedTCP::Server, {"0.0.0.0:8000"});
|
PIIODevice::createFromFullPath("ptcp://s::8000")->cast<PIPackedTCP>(); // new PIPackedTCP(PIPackedTCP::Server, {"0.0.0.0:8000"});
|
||||||
PIPackedTCP * tcp_c = PIIODevice::createFromFullPath("ptcp://c:127.0.0.1:8000")
|
PIPackedTCP * tcp_c = PIIODevice::createFromFullPath("ptcp://c:127.0.0.1:8000")
|
||||||
->cast<PIPackedTCP>(); // new PIPackedTCP(PIPackedTCP::Client, {"127.0.0.1:8000"});
|
->cast<PIPackedTCP>(); // new PIPackedTCP(PIPackedTCP::Client, {"127.0.0.1:8000"});
|
||||||
@@ -78,7 +78,7 @@ int main(int argc, char * argv[]) {
|
|||||||
// piCout << tcp_s->constructFullPath();
|
// piCout << tcp_s->constructFullPath();
|
||||||
delete tcp_s;
|
delete tcp_s;
|
||||||
delete tcp_c;
|
delete tcp_c;
|
||||||
return 0;
|
return 0;*/
|
||||||
/*PITimer timer(tfunc);
|
/*PITimer timer(tfunc);
|
||||||
// timer.addDelimiter(2);
|
// timer.addDelimiter(2);
|
||||||
timer.addDelimiter(40, tfunc4);
|
timer.addDelimiter(40, tfunc4);
|
||||||
@@ -100,6 +100,7 @@ int main(int argc, char * argv[]) {
|
|||||||
PIStateLambda * s1 = new PIStateLambda([] { piCout << "+ enter s1"; }, [] { piCout << "- exit s1"; }, "s1");
|
PIStateLambda * s1 = new PIStateLambda([] { piCout << "+ enter s1"; }, [] { piCout << "- exit s1"; }, "s1");
|
||||||
PIStateLambda * s2 = new PIStateLambda([] { piCout << "+ enter s2"; }, [] { piCout << "- exit s2"; }, "s2");
|
PIStateLambda * s2 = new PIStateLambda([] { piCout << "+ enter s2"; }, [] { piCout << "- exit s2"; }, "s2");
|
||||||
PIStateLambda * s3 = new PIStateLambda([] { piCout << "+ enter s3"; }, [] { piCout << "- exit s3"; }, "s3");
|
PIStateLambda * s3 = new PIStateLambda([] { piCout << "+ enter s3"; }, [] { piCout << "- exit s3"; }, "s3");
|
||||||
|
PIStateLambda * s4 = new PIStateLambda([] { piCout << "+ enter s4"; }, [] { piCout << "- exit s4"; }, "s4");
|
||||||
PIStateLambda * s11 = new PIStateLambda([] { piCout << " + enter s11"; }, [] { piCout << " - exit s11"; }, "s11");
|
PIStateLambda * s11 = new PIStateLambda([] { piCout << " + enter s11"; }, [] { piCout << " - exit s11"; }, "s11");
|
||||||
PIStateLambda * s12 = new PIStateLambda([] { piCout << " + enter s12"; }, [] { piCout << " - exit s12"; }, "s12");
|
PIStateLambda * s12 = new PIStateLambda([] { piCout << " + enter s12"; }, [] { piCout << " - exit s12"; }, "s12");
|
||||||
PIStateLambda * s13 = new PIStateLambda([] { piCout << " + enter s13"; }, [] { piCout << " - exit s13"; }, "s13");
|
PIStateLambda * s13 = new PIStateLambda([] { piCout << " + enter s13"; }, [] { piCout << " - exit s13"; }, "s13");
|
||||||
@@ -111,33 +112,35 @@ int main(int argc, char * argv[]) {
|
|||||||
PIStateLambda * s213 = new PIStateLambda([] { piCout << " + enter s213"; }, [] { piCout << " - exit s213"; }, "s213");
|
PIStateLambda * s213 = new PIStateLambda([] { piCout << " + enter s213"; }, [] { piCout << " - exit s213"; }, "s213");
|
||||||
PIStateFinal * s214 = new PIStateFinal([] { piCout << " + enter s214 final"; }, "s214f");
|
PIStateFinal * s214 = new PIStateFinal([] { piCout << " + enter s214 final"; }, "s214f");
|
||||||
|
|
||||||
root->addStates({s1, s2, s3});
|
root->addStates({s1, s2, s3, s4});
|
||||||
s1->addStates({s11, s12, s13});
|
// s1->addStates({s11, s12, s13});
|
||||||
s2->addStates({s21, s22, s23});
|
// s2->addStates({s21, s22, s23});
|
||||||
s21->addStates({s211, s212, s213});
|
// s21->addStates({s211, s212, s213});
|
||||||
// root->addState(s214);
|
// root->addState(s214);
|
||||||
|
|
||||||
s2->setParallel(true);
|
s2->setParallel(true);
|
||||||
|
|
||||||
root->setInitialState(s2);
|
root->setInitialState(s1);
|
||||||
s1->setInitialState(s11);
|
s1->setInitialState(s11);
|
||||||
s2->setInitialState(s21);
|
s2->setInitialState(s21);
|
||||||
s21->setInitialState(s213);
|
s21->setInitialState(s213);
|
||||||
|
|
||||||
// s213->addTransition(s13, meVoid)->addAction([] { piCout << "action transition s21 -> s22"; });
|
// s213->addTransition(s13, meVoid)->addAction([] { piCout << "action transition s21 -> s22"; });
|
||||||
// s3->addTransition(s212, meVoid)->addAction([] { piCout << "action transition s1 -> s213"; });
|
// s3->addTransition(s212, meVoid)->addAction([] { piCout << "action transition s1 -> s213"; });
|
||||||
s2->addTransition(s3, meVoid);
|
s1->addTransition(s2, meVoid)->addAction([root] { root->postEvent(meInt, 1); });
|
||||||
s2->addTimeoutTransition(s3, .5_s);
|
s2->addTransition(s3, meInt)->addGuard([](int i) { return i == 1; })->addAction([root] { root->postEvent(meInt, 2); });
|
||||||
// s3->addTransition(s1, meIntString)->addGuard([](int i, PIString str) { return i == 2 && str == "hello"; });
|
s3->addTransition(s4, meInt)->addGuard([](int i) { return i == 2; })->addAction([root] { root->postEvent(meInt, 3); });
|
||||||
|
// s2->addTimeoutTransition(s3, .5_s);
|
||||||
|
// s3->addTransition(s1, meIntString)->addGuard([](int i, PIString str) { return i == 2 && str == "hello"; });
|
||||||
|
|
||||||
root->start();
|
root->start();
|
||||||
piCout << "initial" << root->isRunning() << "\n";
|
piCout << "initial" << root->isRunning() << "\n";
|
||||||
piCout << "active atomics" << root->activeAtomics();
|
// piCout << "active atomics" << root->activeAtomics();
|
||||||
root->print();
|
root->print();
|
||||||
|
|
||||||
// piCout << "\npost event";
|
piCout << "\npost event";
|
||||||
// posted = root->postEvent(meVoid);
|
posted = root->postEvent(meVoid);
|
||||||
// piCout << "posted" << posted << "\n";
|
piCout << "posted" << posted << "\n";
|
||||||
// piCout << "active atomics" << root->activeAtomics();
|
// piCout << "active atomics" << root->activeAtomics();
|
||||||
piSleep(1.);
|
piSleep(1.);
|
||||||
root->print();
|
root->print();
|
||||||
|
|||||||
Reference in New Issue
Block a user