Mind: Implement initialize/finalizeBodyReq()

We've done a lot of general work on the init sequencing.
This commit is contained in:
2025-09-12 16:09:26 -04:00
parent b99b147959
commit 25a9721f92
10 changed files with 294 additions and 163 deletions
+23 -37
View File
@@ -47,7 +47,7 @@ void ComponentThread::marionetteMain(ComponentThread& self)
self.initializeTls();
mrntt::exitCode = EXIT_SUCCESS;
static boost::asio::signal_set signals(self.getIoService(), SIGINT);
bool callFinalizeReq = false, callShutdownSalmanoffReq = false;
bool callFinalizeReq = false, callShutdownSalmanoff = false;
try {
// Register SIGINT (Ctrl+C) and SIGSEGV handlers
@@ -88,6 +88,9 @@ void ComponentThread::marionetteMain(ComponentThread& self)
throw JustPrintUsageNoError(options);
}
initializeSalmanoff();
callShutdownSalmanoff = true;
self.getIoService().post([]()
{
/** EXPLANATION:
@@ -109,22 +112,17 @@ void ComponentThread::marionetteMain(ComponentThread& self)
* easier to implement.
*/
globalMind->initializeReq(
[](bool success)
[](bool success)
{
if (!success)
{
if (success) {
initializeSalmanoff([](bool success) {
if (!success) {
std::cerr << "Failed to initialize "
"Salmanoff" << '\n';
}
});
}
else {
std::cerr << "Failed to initialize Mind object "
"(threads)" << '\n';
}
std::cerr << "Failed to initialize Mind object "
"(threads)" << '\n';
}
);
std::cout << "Mrntt: Mind object (threads) initialized."
<< '\n';
});
});
std::cout << __func__ << ": Entering event loop" << "\n";
@@ -188,43 +186,26 @@ void ComponentThread::marionetteMain(ComponentThread& self)
}
*out << outUsageMsg << e.what() << std::endl;
callShutdownSalmanoffReq = callFinalizeReq = true;
callFinalizeReq = true;
}
catch (const std::exception& e)
{
std::cerr << __func__ << ": Exception occurred: " << e.what()
<< std::endl;
mrntt::exitCode = EXIT_FAILURE;
callShutdownSalmanoffReq = callFinalizeReq = true;
callShutdownSalmanoff = callFinalizeReq = true;
}
catch (...)
{
std::cerr << __func__ << ": Unknown exception occurred" << std::endl;
mrntt::exitCode = EXIT_FAILURE;
callShutdownSalmanoffReq = callFinalizeReq = true;
}
if (callShutdownSalmanoffReq)
{
shutdownSalmanoff(
[](bool success)
{
if (success) {
std::cout << "Salmanoff shutdown completed successfully"
<< std::endl;
} else {
std::cerr << "Salmanoff shutdown failed" << std::endl;
}
mrntt::mrntt->getIoService().stop();
}
);
self.getIoService().reset();
self.getIoService().run();
callShutdownSalmanoff = callFinalizeReq = true;
}
if (callFinalizeReq)
{
globalMind->finalizeReq([](bool success) {
globalMind->finalizeReq([](bool success)
{
if (!success) {
std::cerr << "Failed to finalize Mind object (threads)" << '\n';
}
@@ -233,6 +214,11 @@ void ComponentThread::marionetteMain(ComponentThread& self)
self.getIoService().reset();
self.getIoService().run();
}
if (callShutdownSalmanoff) {
shutdownSalmanoff();
}
}
} // namespace smo
+6 -84
View File
@@ -7,100 +7,22 @@
namespace smo {
class InitializeSalmanoffReq
: public AsynchronousContinuation<initializeSalmanoffCbFn>
{
public:
InitializeSalmanoffReq(initializeSalmanoffCbFn cb)
: AsynchronousContinuation(std::move(cb))
{}
// Callback methods for the initialization sequence
void initializeSalmanoffReq1(
std::shared_ptr<InitializeSalmanoffReq> context,
smo::AsynchronousLoop &results
)
{
std::cout << __func__ << ": Done. " << results.nSucceeded
<< " succeeded, " << results.nFailed << " failed." << std::endl;
context->originalCbFn(true);
}
};
void initializeSalmanoff(
initializeSalmanoffCbFn callback)
void initializeSalmanoff(void)
{
std::cout << __func__ << ": Entered." << std::endl;
std::shared_ptr<ComponentThread> mrntt = ComponentThread::getMrntt();
auto request = std::make_shared<InitializeSalmanoffReq>(
std::move(callback));
sense_api::SenseApiManager::getInstance().initialize();
device::DeviceManager::getInstance().initialize();
device::DeviceManager::getInstance().collateAllDapSpecs();
device::DeviceManager::getInstance().parseAllDapSpecs();
std::cout << device::DeviceManager::stringifyDeviceSpecs() << std::endl;
/** EXPLANATION:
* The ComponentThread instance we pass in here is the one that will be used
* by Senseapi libs to perform device-independent background operations.
* For example, liblivoxProto1's BroadcastListener will use this thread to
* listen for UDP broadcast dgrams from Livox devices.
*
* Right now we use Marionette, but there's a strong argument for using
* Body instead since it's meant to handle device-management operations.
*/
sense_api::SenseApiManager::getInstance().loadAllSenseApiLibsFromOptions(
mrntt);
std::cout << sense_api::SenseApiManager::getInstance().stringifyLibs()
<< std::endl;
if (OptionParser::getOptions().verbose) {
std::cout << __func__ << ": About to initializeAllSenseApiLibs" << '\n';
}
sense_api::SenseApiManager::getInstance().initializeAllSenseApiLibs();
if (OptionParser::getOptions().verbose) {
std::cout << __func__ << ": About to attachAllSenseDevicesFromSpecs" << '\n';
}
sense_api::SenseApiManager::getInstance().attachAllSenseDevicesFromSpecsReq(
std::bind(
&InitializeSalmanoffReq::initializeSalmanoffReq1,
request.get(), request,
std::placeholders::_1));
}
class ShutdownSalmanoffReq
: public InitializeSalmanoffReq
{
public:
using InitializeSalmanoffReq::InitializeSalmanoffReq;
// Callback methods for the shutdown sequence
void shutdownSalmanoffReq1(
std::shared_ptr<ShutdownSalmanoffReq> context,
smo::AsynchronousLoop &results
)
{
sense_api::SenseApiManager::getInstance().finalizeAllSenseApiLibs();
std::cout << __func__ << ": Done. " << results.nSucceeded
<< " succeeded, " << results.nFailed << " failed." << std::endl;
context->originalCbFn(true);
}
};
void shutdownSalmanoff(shutdownSalmanoffCbFn callback)
void shutdownSalmanoff(void)
{
std::cout << __func__ << ": Entered." << std::endl;
// Create the shutdown request object to hold state and callbacks
auto request = std::make_shared<ShutdownSalmanoffReq>(std::move(callback));
sense_api::SenseApiManager::getInstance().detachAllSenseDevicesReq(
std::bind(
&ShutdownSalmanoffReq::shutdownSalmanoffReq1,
request.get(), request,
std::placeholders::_1));
device::DeviceManager::getInstance().finalize();
sense_api::SenseApiManager::getInstance().finalize();
}
} // namespace smo