diff --git a/smocore/componentThread.cpp b/smocore/componentThread.cpp index dc87253..46a3586 100644 --- a/smocore/componentThread.cpp +++ b/smocore/componentThread.cpp @@ -96,6 +96,13 @@ void ComponentThread::main(ComponentThread& self) std::cout << self.name << ":" << __func__ << ": Entering event loop" <<"\n"; + /* We loop here because when an exception is caught, we need to first catch + * it in the catch blocks. We bubble the exception to mrntt in the catch + * blocks, and then we loop here to await control messages from mrntt. + * + * We can't just exit on our own. Rather, we must wait for mrntt to tell us + * to exit. When we wish to finally exit, we set keepLooping to false. + */ for (self.keepLooping = true; self.keepLooping;) { try { @@ -118,7 +125,7 @@ void ComponentThread::main(ComponentThread& self) } } - std::cout << self.name << ":" << __func__ << ": Exiting event loop" << "\n"; + std::cout << self.name << ":" << __func__ << ": Exited event loop" << "\n"; } // Thread management method implementations @@ -245,6 +252,8 @@ void ComponentThread::exceptionInd(ComponentThread& thread) currThreadJ->thread.join(); } + + mrntt::mrntt->keepLooping = false; mrntt::mrntt->getIoService().stop(); } ); diff --git a/smocore/include/marionette/marionette.h b/smocore/include/marionette/marionette.h index ec0c1e3..50b3a23 100644 --- a/smocore/include/marionette/marionette.h +++ b/smocore/include/marionette/marionette.h @@ -28,7 +28,7 @@ struct CrtCommandLineArgs static void set(int argc, char *argv[], char *envp[]); }; -int initializeSalmanoff(void); +void initializeSalmanoff(void); } // namespace smo diff --git a/smocore/include/mind.h b/smocore/include/mind.h index 9d7a74e..a270676 100644 --- a/smocore/include/mind.h +++ b/smocore/include/mind.h @@ -12,6 +12,7 @@ namespace smo { class Mind { public: + void initialize(void); void execute(void); public: diff --git a/smocore/marionette/marionette.cpp b/smocore/marionette/marionette.cpp index 40a69ea..d815622 100644 --- a/smocore/marionette/marionette.cpp +++ b/smocore/marionette/marionette.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -57,37 +58,52 @@ void ComponentThread::marionetteMain(ComponentThread& self) return; } - int ret = smo::initializeSalmanoff(); - if (ret != 0) + smo::Mind mind; + + self.getIoService().post([&mind]() { - std::cerr << __func__ << ": Initialization failed with code: " - << ret << std::endl; - mrntt::exitCode = ret; - return; - } + try { + initializeSalmanoff(); + mind.initialize(); + } + catch (const std::exception& e) { + mrntt::exitCode = EXIT_FAILURE; + throw; + } - /* Start the threads */ - for (auto& componentThread : smo::ComponentThread::componentThreads) - { - // Post startThread() to the event loop of all threads except MRNTT. - if (componentThread->id == ComponentThread::MRNTT) { continue; } - - // JOLT the thread. - componentThread->getIoService().post([componentThread]() - { componentThread->getIoService().stop(); } - ); - - // Now tell it to execute its initialization sequence. - componentThread->startThreadReq(); - } - - body::body->getIoService().post([]{ - throw std::runtime_error("test exception"); - }); + body::body->getIoService().post([]{ + throw std::runtime_error("test exception"); + }); + }); std::cout << __func__ << ": Entering event loop" << "\n"; - self.getIoService().reset(); - self.getIoService().run(); + + /* We loop here because when an exception occurs in mrntt, we need to + * both direct the mind threads to exit gracefully, and then we also + * need to post messages to our own event loop to initiate our own + * orderly exit. So we loop here to re-enter the event loop, both + * to receive the ACK messages from the mind threads, and to post + * messages to our own event loop to initiate our own orderly exit. + */ + for (self.keepLooping = true; self.keepLooping;) + { + try { + self.getIoService().reset(); + self.getIoService().run(); + } + catch (const std::exception& e) + { + std::cerr << self.name << ":" << __func__ + << ": Exception occurred: " << e.what() << "\n"; + } + catch (...) + { + std::cerr << self.name << ":" << __func__ + << ": Unknown exception occurred" << "\n"; + } + } + + std::cout << __func__ << ": Exited event loop" << "\n"; } catch (const std::exception& e) { diff --git a/smocore/marionette/salmanoff.cpp b/smocore/marionette/salmanoff.cpp index 9a74126..1434c83 100644 --- a/smocore/marionette/salmanoff.cpp +++ b/smocore/marionette/salmanoff.cpp @@ -4,7 +4,7 @@ namespace smo { -int initializeSalmanoff(void) +void initializeSalmanoff(void) { std::cout << __func__ << ": Entered." << std::endl; @@ -21,7 +21,6 @@ std::cerr << "About to attachAllSenseDevicesFromSpecs" << std::endl; std::cerr << "Done attachAllSenseDevicesFromSpecs" << std::endl; std::cout << __func__ << ": Done." << std::endl; - return 0; } } // namespace smo diff --git a/smocore/mind.cpp b/smocore/mind.cpp index 38d08ed..64d17ea 100644 --- a/smocore/mind.cpp +++ b/smocore/mind.cpp @@ -1,2 +1,25 @@ #include +#include + +namespace smo { + +void Mind::initialize() +{ + /* Start the threads */ + for (auto& componentThread : smo::ComponentThread::componentThreads) + { + // Post startThread() to the event loop of all threads except MRNTT. + if (componentThread->id == ComponentThread::MRNTT) { continue; } + + // JOLT the thread. + componentThread->getIoService().post([componentThread]() + { componentThread->getIoService().stop(); } + ); + + // Now tell it to execute its initialization sequence. + componentThread->startThreadReq(); + } +} + +} // namespace smo