Files
salmanoff/smocore/marionette/lifetime.cpp
T

116 lines
2.6 KiB
C++

#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <boost/asio/post.hpp>
#include <componentThread.h>
#include <deviceManager/deviceManager.h>
#include <marionette/marionette.h>
#include <marionette/marionetteThread.h>
#include <mindManager/mindManager.h>
#include <spinscale/componentThread.h>
namespace smo {
namespace mrntt {
namespace {
void assertMarionetteThread()
{
auto self = sscl::ComponentThread::getSelf();
if (self->id != SmoThreadId::MRNTT)
{
throw std::runtime_error(
std::string(__func__)
+ ": Must be executed on Marionette thread");
}
}
} // namespace
void MarionetteComponent::holdInitializeCReq(
std::function<void()> completion)
{
initializeLifetimeSucceeded = false;
initializeLifetimeExceptionPtr = nullptr;
initializeCReqInvoker.emplace(initializeCReq(
initializeLifetimeExceptionPtr, std::move(completion)));
}
void MarionetteComponent::holdFinalizeCReq(
std::function<void()> completion)
{
finalizeCReqInvoker.emplace(finalizeCReq(
finalizeLifetimeExceptionPtr, std::move(completion)));
}
MrnttNonViralPostingInvoker MarionetteComponent::initializeCReq(
[[maybe_unused]] std::exception_ptr &exceptionPtr,
[[maybe_unused]] std::function<void()> callback)
{
assertMarionetteThread();
smo::mind::globalMind = std::make_shared<smo::Mind>();
bool mindInitialized = co_await smo::mind::globalMind->initializeCReq();
if (!mindInitialized)
{
std::cerr << __func__ << ": Failed to initialize globalMind"
<< std::endl;
co_return;
}
initializeLifetimeSucceeded = true;
smo::device::DeviceManager::getInstance().initializeDeviceReattacher();
// Call negtrinEventInd on the Director in the final callback
smo::mind::globalMind->director.negtrinEventInd();
co_return;
}
MrnttNonViralPostingInvoker MarionetteComponent::finalizeCReq(
[[maybe_unused]] std::exception_ptr &exceptionPtr,
[[maybe_unused]] std::function<void()> callback)
{
assertMarionetteThread();
smo::device::DeviceManager::getInstance().finalizeDeviceReattacher();
if (!smo::mind::globalMind)
{
co_return;
}
bool mindFinalized = co_await smo::mind::globalMind->finalizeCReq();
if (!mindFinalized)
{
std::cerr << __func__ << ": globalMind finalization failed"
<< std::endl;
}
co_return;
}
void MarionetteComponent::handleLoopExceptionHook()
{
sscl::pptr::exitCode = EXIT_FAILURE;
exceptionInd();
}
void MarionetteComponent::exceptionInd()
{
auto puppeteer = sscl::ComponentThread::getPptr();
boost::asio::post(
puppeteer->getIoService(),
[]
{
mrntt.holdFinalizeCReq(
[]() { marionetteFinalizeReqCb(true); });
});
}
} // namespace mrntt
} // namespace smo