From c457ee7aca9e8992536c0a018d1a0f92947e955c Mon Sep 17 00:00:00 2001 From: Hayodea Hakol Date: Sun, 10 Aug 2025 13:12:17 -0400 Subject: [PATCH] smo::Mind instance now global; track & manage JOLT state in Mind We moved the instance of smo::Mind to global scope. I suppose we'll only support one instance of Mind per SMO process at least for now. We now track the state of Mind threads' JOLT-waiting. This allows us to centralize the Mind thread shutdown logic. Mind::finalizeReq() now takes care of all Mind thread shutdown state logic by tracking whether Mind threads need to be JOLTed first before being told to exit. --- smocore/componentThread.cpp | 9 ++++---- smocore/include/mind.h | 10 ++++++++- smocore/marionette/marionette.cpp | 22 ++++-------------- smocore/mind.cpp | 37 +++++++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/smocore/componentThread.cpp b/smocore/componentThread.cpp index aa2bca4..ea890e6 100644 --- a/smocore/componentThread.cpp +++ b/smocore/componentThread.cpp @@ -1,9 +1,10 @@ +#include #include -#include -#include #include #include -#include +#include +#include +#include namespace smo { @@ -377,7 +378,7 @@ void ComponentThread::exceptionInd(ComponentThread& thread) std::cerr << "Mrntt: Exception occurred: in thread " << thread.name << ". Killing Salmanoff." << "\n"; - ComponentThread::exitAllMindThreadsReq( + smo::mind.finalizeReq( []() { mrntt::mrntt->keepLooping = false; diff --git a/smocore/include/mind.h b/smocore/include/mind.h index 81f80c3..50b6145 100644 --- a/smocore/include/mind.h +++ b/smocore/include/mind.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -12,9 +13,11 @@ namespace smo { class Mind { public: + Mind(void) : threadsHaveBeenJolted(false) {} + void initialize(void); void execute(void); - void finalize(void); + void finalizeReq(std::function callback); public: std::thread directorThread; @@ -23,8 +26,13 @@ public: director::Director director; simulator::Simulator canvas; + +private: + bool threadsHaveBeenJolted; }; +extern Mind mind; + } // namespace smo #endif diff --git a/smocore/marionette/marionette.cpp b/smocore/marionette/marionette.cpp index b77ca63..8ea1da9 100644 --- a/smocore/marionette/marionette.cpp +++ b/smocore/marionette/marionette.cpp @@ -57,29 +57,15 @@ void ComponentThread::marionetteMain(ComponentThread& self) /* We could make RAII guard classes to always shutdown the mind * threads properly in these pre-event loop situations. */ - self.getIoService().post([&options]() - { - ComponentThread::joltAllMindThreadsReq( - [&options]() - { - ComponentThread::exitAllMindThreadsReq( - [&options]() - { - std::cout << __func__ << ": " << options.getUsage() - << '\n'; - mrntt::mrntt->getIoService().stop(); - } - ); - }); + mind.finalizeReq([]{ + mrntt::mrntt->getIoService().stop(); }); self.getIoService().reset(); self.getIoService().run(); return; } - smo::Mind mind; - - self.getIoService().post([&mind]() + self.getIoService().post([]() { try { initializeSalmanoff(); @@ -128,7 +114,7 @@ void ComponentThread::marionetteMain(ComponentThread& self) } std::cout << __func__ << ": Exited event loop" << "\n"; - mind.finalize(); + mind.finalizeReq(nullptr); shutdownSalmanoff(); } catch (const std::exception& e) diff --git a/smocore/mind.cpp b/smocore/mind.cpp index 4bf686b..2aa7301 100644 --- a/smocore/mind.cpp +++ b/smocore/mind.cpp @@ -4,6 +4,8 @@ namespace smo { +Mind mind; + void Mind::initialize() { /* Distribute threads across available CPUs */ @@ -20,8 +22,9 @@ void Mind::initialize() /* Jolt the threads, then start them */ ComponentThread::joltAllMindThreadsReq( - []() + [this]() { + this->threadsHaveBeenJolted = true; std::cout << "Mrntt: All mind threads JOLTed." << "\n"; ComponentThread::startAllMindThreadsReq( []() @@ -33,8 +36,38 @@ void Mind::initialize() ); } -void Mind::finalize(void) +void Mind::finalizeReq(std::function callback) { + /* If the threads haven't been jolted, we need to do that first, because + * otherwise they'll just enter their main loops and wait for control + * messages from mrntt after processing the exit request. + */ + if (!threadsHaveBeenJolted) + { + ComponentThread::joltAllMindThreadsReq( + [this, callback]() + { + this->threadsHaveBeenJolted = true; + ComponentThread::exitAllMindThreadsReq( + [callback]() + { + std::cout << "Mrntt: All mind threads exited." << "\n"; + if (callback) { callback(); } + } + ); + } + ); + } + else + { + ComponentThread::exitAllMindThreadsReq( + [callback]() + { + std::cout << "Mrntt: All mind threads exited." << "\n"; + if (callback) { callback(); } + } + ); + } } } // namespace smo