e276fcbdce
Mrntt now has the event loop structure required to orderly shut itself
down when it itself generates an exception. We can now post a message
within the catch{} blocks for Mrntt's event loop, telling Mrntt
to shut down the Mind threads and then shut itself down.
We also split the code to initialize threads etc out of mrntt and
put it into the Mind:: namespace.
127 lines
3.2 KiB
C++
127 lines
3.2 KiB
C++
#include <config.h>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <exception>
|
|
#include <opts.h>
|
|
#include <mind.h>
|
|
#include <componentThread.h>
|
|
#include <marionette/marionette.h>
|
|
|
|
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<int> 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 = 0;
|
|
|
|
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.getUsage() << '\n';
|
|
|
|
mrntt::exitCode = EXIT_FAILURE;
|
|
return;
|
|
}
|
|
|
|
if (options.printUsage)
|
|
{
|
|
std::cout << __func__ << ": " << options.getUsage() << std::endl;
|
|
mrntt::exitCode = EXIT_SUCCESS;
|
|
return;
|
|
}
|
|
|
|
smo::Mind mind;
|
|
|
|
self.getIoService().post([&mind]()
|
|
{
|
|
try {
|
|
initializeSalmanoff();
|
|
mind.initialize();
|
|
}
|
|
catch (const std::exception& e) {
|
|
mrntt::exitCode = EXIT_FAILURE;
|
|
throw;
|
|
}
|
|
|
|
body::body->getIoService().post([]{
|
|
throw std::runtime_error("test exception");
|
|
});
|
|
});
|
|
|
|
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;)
|
|
{
|
|
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)
|
|
{
|
|
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
|