#include #include #include #include #include #include #include #include #include namespace smo { CrtCommandLineArgs crtCommandLineArgs(0, nullptr, nullptr); void CrtCommandLineArgs::set(int argc, char *argv[], char *envp[]) { crtCommandLineArgs = CrtCommandLineArgs(argc, argv, envp); } namespace mrntt { std::atomic exitCode; } void ComponentThread::marionetteMain(ComponentThread& self) { // Wait for CRT's main() to post us the command line args. std::cout << __func__ << ": Waiting for command line JOLT" << std::endl; self.getIoService().run(); self.initializeTls(); mrntt::exitCode = EXIT_SUCCESS; try { OptionParser &options = OptionParser::getOptions(); std::cout << __func__ << ": " << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl; try { options.parseArguments( crtCommandLineArgs.argc, crtCommandLineArgs.argv, crtCommandLineArgs.envp); std::cout << __func__ << ": " << options.stringifyOptions() << std::endl; } catch (const std::invalid_argument& e) { std::cerr << __func__ << ": Exception occurred: " << e.what() << '\n'; options.printUsage = true; mrntt::exitCode = EXIT_FAILURE; } if (options.printUsage) { /* We could make RAII guard classes to always shutdown the mind * threads properly in these pre-event loop situations. */ mind.finalizeReq([]{ mrntt::mrntt->getIoService().stop(); }); self.getIoService().reset(); self.getIoService().run(); return; } self.getIoService().post([]() { try { initializeSalmanoff(); mind.initialize(); } catch (const std::exception& e) { mrntt::exitCode = EXIT_FAILURE; throw; } }); std::cout << __func__ << ": Entering event loop" << "\n"; /* 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;) { bool sendExceptionInd = false; try { 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.exceptionInd(self); } } std::cout << __func__ << ": Exited event loop" << "\n"; mind.finalizeReq(nullptr); shutdownSalmanoff(); } catch (const std::exception& e) { std::cerr << __func__ << ": Exception occurred: " << e.what() << std::endl; mrntt::exitCode = EXIT_FAILURE; return; } catch (...) { std::cerr << __func__ << ": Unknown exception occurred" << std::endl; mrntt::exitCode = EXIT_FAILURE; return; } std::cout << __func__ << ": Exiting normally" << std::endl; } } // namespace smo