#include #include #include #include #include namespace smo { std::string ComponentThread::getThreadName(ThreadId id) { // Cast ThreadId to SmoThreadId for validation and lookup SmoThreadId smoId = static_cast(id); if (static_cast(smoId) >= static_cast(SmoThreadId::N_ITEMS)) { throw std::runtime_error(std::string(__func__) + ": Invalid thread ID"); } // Use function-local static to ensure proper initialization order static const std::string threadNames[static_cast(SmoThreadId::N_ITEMS)] = { "mrntt", "director", "simulator", "subconscious", "body", "world" }; return threadNames[static_cast(smoId)]; } void PuppetThread::main(PuppetThread& self) { std::string threadName = "smo:" + self.name; pthread_setname_np(pthread_self(), threadName.c_str()); self.getIoService().run(); self.initializeTls(); 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;) { bool sendExceptionInd = false; try { /** EXPLANATION: * This reset() call is crucial for async bridging patterns * to work. * When the outermost thread's io_service is stop()ped (e.g., * from JOLT sequence), it won't process any new work until * reset() is called, even if nested async operations try to * post work to it. This means async bridges invoked from * the outermost thread main sequence won't work until this * reset() call. */ self.getIoService().reset(); self.getIoService().run(); } catch (const std::exception& e) { sendExceptionInd = true; std::cerr << self.name << ":" << __func__ << ": Exception occurred: " << e.what() << "\n"; } catch (...) { sendExceptionInd = true; std::cerr << self.name << ":" << __func__ << ": Unknown exception occurred" << "\n"; } if (sendExceptionInd) { self.handleException(); } } std::cout << self.name << ":" << __func__ << ": Exited event loop" << "\n"; } } // namespace smo