Async: add sh_ptr<ContinuationChainLink> to Callback<>

This change enables us to finally implement the tracing of
continuations backward from the point of acquisition for deadlock
debugging.
This commit is contained in:
2025-09-27 18:30:09 -04:00
parent 2212aec080
commit 782bcd4567
26 changed files with 384 additions and 269 deletions
+11 -10
View File
@@ -4,6 +4,7 @@
#include <optional>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <callback.h>
#include <user/senseApiDesc.h>
#include "protocol.h"
#include "core.h"
@@ -84,7 +85,7 @@ public:
GetOrCreateDeviceReq(
DeviceManager& mgr,
std::shared_ptr<Device> device,
livoxProto1_getOrCreateDeviceReqCbFn cb)
smo::Callback<livoxProto1_getOrCreateDeviceReqCbFn> cb)
: smo::NonPostedAsynchronousContinuation<
livoxProto1_getOrCreateDeviceReqCbFn>(std::move(cb)),
deviceManager(mgr), pendingDevice(device)
@@ -130,7 +131,7 @@ void DeviceManager::getOrCreateDeviceReq(
int handshakeTimeoutMs, int retryDelayMs,
const std::string& smoIp, uint8_t smoSubnetNbits,
uint16_t dataPort, uint16_t cmdPort, uint16_t imuPort,
livoxProto1_getOrCreateDeviceReqCbFn callback)
smo::Callback<livoxProto1_getOrCreateDeviceReqCbFn> callback)
{
// Validate smoIp format using Boost.Asio IPv4 validation
if (!smoIp.empty() && !comms::isValidIPv4(smoIp))
@@ -154,7 +155,7 @@ void DeviceManager::getOrCreateDeviceReq(
if (existingDevice)
{
// Device already exists and is connected, return it
callback(true, existingDevice.value());
callback.callbackFn(true, existingDevice.value());
return;
}
@@ -171,9 +172,9 @@ void DeviceManager::getOrCreateDeviceReq(
// Start the connection process - only add to collection on success
request->pendingDevice->connectReq(
std::bind(
{request, std::bind(
&DeviceManager::GetOrCreateDeviceReq::getOrCreateDeviceReq1,
request.get(), request, std::placeholders::_1));
request.get(), request, std::placeholders::_1)});
}
class DeviceManager::DestroyDeviceReq
@@ -188,7 +189,7 @@ public:
DestroyDeviceReq(
DeviceManager& mgr,
std::shared_ptr<Device> device,
livoxProto1_destroyDeviceReqCbFn cb)
smo::Callback<livoxProto1_destroyDeviceReqCbFn> cb)
: smo::NonPostedAsynchronousContinuation<
livoxProto1_destroyDeviceReqCbFn>(std::move(cb)),
deviceManager(mgr), pendingDevice(device)
@@ -218,7 +219,7 @@ public:
void DeviceManager::destroyDeviceReq(
std::shared_ptr<Device> dev,
livoxProto1_destroyDeviceReqCbFn callback
smo::Callback<livoxProto1_destroyDeviceReqCbFn> callback
)
{
/** EXPLANATION:
@@ -230,7 +231,7 @@ void DeviceManager::destroyDeviceReq(
if (!device)
{
callback(false);
callback.callbackFn(false);
return;
}
@@ -238,9 +239,9 @@ void DeviceManager::destroyDeviceReq(
*this, device, std::move(callback));
device->disconnectReq(
std::bind(
{request, std::bind(
&DeviceManager::DestroyDeviceReq::destroyDeviceReq1,
request.get(), request, std::placeholders::_1));
request.get(), request, std::placeholders::_1)});
}
void main(const std::shared_ptr<smo::ComponentThread> &componentThread,
+3 -2
View File
@@ -10,6 +10,7 @@
#include "device.h"
#include "broadcastListener.h"
#include "livoxProto1.h"
#include <callback.h>
namespace livoxProto1 {
@@ -27,11 +28,11 @@ public:
int handshakeTimeoutMs, int retryDelayMs,
const std::string& smoIp, uint8_t smoSubnetNbits,
uint16_t dataPort, uint16_t cmdPort, uint16_t imuPort,
livoxProto1_getOrCreateDeviceReqCbFn callback);
smo::Callback<livoxProto1_getOrCreateDeviceReqCbFn> callback);
void destroyDeviceReq(
std::shared_ptr<Device> device,
livoxProto1_destroyDeviceReqCbFn callback);
smo::Callback<livoxProto1_destroyDeviceReqCbFn> callback);
std::optional<std::shared_ptr<Device>> getDevice(
const std::string &deviceIdentifier);
+28 -24
View File
@@ -16,6 +16,7 @@
#include <boost/asio.hpp>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <callback.h>
#include "device.h"
#include "protocol.h"
#include "core.h"
@@ -127,7 +128,7 @@ private:
std::unique_ptr<boost::asio::deadline_timer> retryTimer;
public:
ConnectReq(Device& dev, Device::connectReqCbFn cb)
ConnectReq(Device& dev, smo::Callback<Device::connectReqCbFn> cb)
: smo::NonPostedAsynchronousContinuation<Device::connectReqCbFn>(
std::move(cb)), device(dev)
{}
@@ -160,9 +161,9 @@ public:
// Try direct connect by device identifier
context->device.connectByDeviceIdentifierReq(
std::bind(&ConnectReq::connectReq2, context.get(), context,
{context, std::bind(&ConnectReq::connectReq2, context.get(), context,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
std::placeholders::_3)});
}
void connectReq2(
@@ -219,9 +220,9 @@ public:
}
context->device.connectToKnownDeviceReq(
std::bind(&ConnectReq::connectReq4, context.get(), context,
{context, std::bind(&ConnectReq::connectReq4, context.get(), context,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
std::placeholders::_3)});
}
void connectReq4(
@@ -243,7 +244,7 @@ public:
}
};
void Device::connectReq(Device::connectReqCbFn callback)
void Device::connectReq(smo::Callback<Device::connectReqCbFn> callback)
{
// Create the connection request object to hold state and callbacks
auto request = std::make_shared<ConnectReq>(*this, std::move(callback));
@@ -254,10 +255,10 @@ void Device::connectReq(Device::connectReqCbFn callback)
}
connectToKnownDeviceReq(
std::bind(
{request, std::bind(
&ConnectReq::connectReq1, request.get(), request,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
std::placeholders::_3)});
}
class Device::ConnectToKnownDeviceReq
@@ -269,7 +270,7 @@ public:
std::string deviceIP;
std::shared_ptr<livoxProto1::comms::DiscoveredDevice> deviceInfo;
ConnectToKnownDeviceReq(Device& dev, Device::connectToKnownDeviceReqCbFn cb)
ConnectToKnownDeviceReq(Device& dev, smo::Callback<Device::connectToKnownDeviceReqCbFn> cb)
: smo::NonPostedAsynchronousContinuation<
Device::connectToKnownDeviceReqCbFn>(std::move(cb)), device(dev)
{}
@@ -297,7 +298,7 @@ public:
* broadcastListener.
*/
void Device::connectToKnownDeviceReq(
Device::connectToKnownDeviceReqCbFn callback
smo::Callback<Device::connectToKnownDeviceReqCbFn> callback
)
{
// Create the connection request object to hold state and callbacks
@@ -357,10 +358,10 @@ void Device::connectToKnownDeviceReq(
// Execute handshake with the known device using async method
request->device.executeHandshakeReq(
request->deviceIP,
std::bind(
{request, std::bind(
&ConnectToKnownDeviceReq::connectToKnownDeviceReq1,
request.get(), request,
std::placeholders::_1, std::placeholders::_2));
std::placeholders::_1, std::placeholders::_2)});
}
class Device::ConnectByDeviceIdentifierReq
@@ -372,7 +373,7 @@ public:
std::string deviceIP;
ConnectByDeviceIdentifierReq(
Device& dev, Device::connectByDeviceIdentifierReqCbFn cb)
Device& dev, smo::Callback<Device::connectByDeviceIdentifierReqCbFn> cb)
: smo::NonPostedAsynchronousContinuation<
Device::connectByDeviceIdentifierReqCbFn>(
std::move(cb)), device(dev)
@@ -398,7 +399,7 @@ public:
};
void Device::connectByDeviceIdentifierReq(
Device::connectByDeviceIdentifierReqCbFn callback
smo::Callback<Device::connectByDeviceIdentifierReqCbFn> callback
)
{
/** EXPLANATION:
@@ -415,7 +416,7 @@ void Device::connectByDeviceIdentifierReq(
// Check if smoIp is provided - required for heuristic construction
if (smoIp.empty())
{
callback(false, "", -1);
callback.callbackFn(false, "", -1);
return;
}
@@ -440,10 +441,10 @@ void Device::connectByDeviceIdentifierReq(
// Execute handshake using async method
request->device.executeHandshakeReq(
request->deviceIP,
std::bind(
{request, std::bind(
&ConnectByDeviceIdentifierReq::connectByDeviceIdentifierReq1,
request.get(), request,
std::placeholders::_1, std::placeholders::_2));
std::placeholders::_1, std::placeholders::_2)});
}
class Device::ExecuteHandshakeReq
@@ -452,7 +453,8 @@ class Device::ExecuteHandshakeReq
{
public:
friend void Device::executeHandshakeReq(
const std::string& deviceIP, Device::executeHandshakeReqCbFn callback);
const std::string& deviceIP,
smo::Callback<Device::executeHandshakeReqCbFn> callback);
enum class SocketState
{
@@ -484,7 +486,7 @@ public:
public:
ExecuteHandshakeReq(
Device& dev, const std::string& deviceIP,
Device::executeHandshakeReqCbFn cb)
smo::Callback<Device::executeHandshakeReqCbFn> cb)
: smo::NonPostedAsynchronousContinuation<Device::executeHandshakeReqCbFn>(
std::move(cb)),
device(dev), deviceIP(deviceIP),
@@ -650,7 +652,8 @@ private:
*/
handshakeFdDesc.async_wait(
boost::asio::posix::stream_descriptor::wait_read,
std::bind(&ExecuteHandshakeReq::executeHandshakeReq1_2, this,
std::bind(
&ExecuteHandshakeReq::executeHandshakeReq1_2, this,
request,
std::placeholders::_1));
}
@@ -830,7 +833,8 @@ private:
};
void Device::executeHandshakeReq(
const std::string& deviceIP, Device::executeHandshakeReqCbFn callback
const std::string& deviceIP,
smo::Callback<Device::executeHandshakeReqCbFn> callback
)
{
// Create the handshake request object to hold state and callbacks
@@ -866,7 +870,7 @@ void Device::executeHandshakeReq(
}
}
void Device::disconnectReq(Device::disconnectReqCbFn callback)
void Device::disconnectReq(smo::Callback<Device::disconnectReqCbFn> callback)
{
// Stop heartbeat first
heartbeatActive.store(false);
@@ -875,7 +879,7 @@ void Device::disconnectReq(Device::disconnectReqCbFn callback)
{
std::cout << __func__ << ": No heartbeat socket available, skipping "
"disconnect message" << std::endl;
callback(true);
callback.callbackFn(true);
return;
}
@@ -911,7 +915,7 @@ void Device::disconnectReq(Device::disconnectReqCbFn callback)
// Close the heartbeat socket
close(heartbeatFd);
heartbeatFd = -1;
callback(true);
callback.callbackFn(true);
}
std::string Device::generateClientDeviceIpFromSerialNumber(
+8 -5
View File
@@ -13,6 +13,7 @@
#include <unistd.h>
#include <boost/asio.hpp>
#include "protocol.h"
#include <callback.h>
// Forward declaration
namespace smo {
@@ -111,13 +112,15 @@ public:
typedef std::function<void(bool success)> disconnectReqCbFn;
// Async connection methods
void connectReq(connectReqCbFn callback);
void connectToKnownDeviceReq(connectToKnownDeviceReqCbFn callback);
void connectReq(smo::Callback<connectReqCbFn> callback);
void connectToKnownDeviceReq(
smo::Callback<connectToKnownDeviceReqCbFn> callback);
void connectByDeviceIdentifierReq(
connectByDeviceIdentifierReqCbFn callback);
smo::Callback<connectByDeviceIdentifierReqCbFn> callback);
void executeHandshakeReq(
const std::string& deviceIP, executeHandshakeReqCbFn callback);
void disconnectReq(disconnectReqCbFn callback);
const std::string& deviceIP,
smo::Callback<executeHandshakeReqCbFn> callback);
void disconnectReq(smo::Callback<disconnectReqCbFn> callback);
// Heartbeat state
std::unique_ptr<boost::asio::deadline_timer> heartbeatTimer;
+3 -2
View File
@@ -1,4 +1,5 @@
#include <stdexcept>
#include <callback.h>
#include "livoxProto1.h"
#include "device.h"
#include "core.h"
@@ -12,7 +13,7 @@ void livoxProto1_getOrCreateDeviceReq(
int handshakeTimeoutMs, int retryDelayMs,
const std::string& smoIp, uint8_t smoSubnetNbits,
uint16_t dataPort, uint16_t cmdPort, uint16_t imuPort,
livoxProto1_getOrCreateDeviceReqCbFn callback
smo::Callback<livoxProto1_getOrCreateDeviceReqCbFn> callback
)
{
// Get the global DeviceManager instance
@@ -35,7 +36,7 @@ void livoxProto1_getOrCreateDeviceReq(
void livoxProto1_destroyDeviceReq(
std::shared_ptr<livoxProto1::Device> device,
livoxProto1_destroyDeviceReqCbFn callback
smo::Callback<livoxProto1_destroyDeviceReqCbFn> callback
)
{
auto& protoState = livoxProto1::getProtoState();
+3 -2
View File
@@ -5,6 +5,7 @@
#include <string>
#include <cstdint>
#include <functional>
#include <callback.h>
// Forward declarations
namespace smo {
@@ -59,12 +60,12 @@ typedef void livoxProto1_getOrCreateDeviceReqFn(
int handshakeTimeoutMs, int retryDelayMs,
const std::string& smoIp, uint8_t smoSubnetNbits,
uint16_t dataPort, uint16_t cmdPort, uint16_t imuPort,
livoxProto1_getOrCreateDeviceReqCbFn callback);
smo::Callback<livoxProto1_getOrCreateDeviceReqCbFn> callback);
typedef std::function<void(bool success)> livoxProto1_destroyDeviceReqCbFn;
typedef void livoxProto1_destroyDeviceReqFn(
std::shared_ptr<livoxProto1::Device> device,
livoxProto1_destroyDeviceReqCbFn callback);
smo::Callback<livoxProto1_destroyDeviceReqCbFn> callback);
livoxProto1_mainFn livoxProto1_main;
+18 -11
View File
@@ -6,6 +6,8 @@
#include <exception>
#include <componentThread.h>
#include <lockSet.h>
#include <callback.h>
#include <asynchronousContinuationChainLink.h>
namespace smo {
@@ -21,10 +23,11 @@ namespace smo {
*/
template <class OriginalCbFnT>
class AsynchronousContinuation
: public AsynchronousContinuationChainLink
{
public:
explicit AsynchronousContinuation(OriginalCbFnT originalCbFn)
: originalCbFn(std::move(originalCbFn))
explicit AsynchronousContinuation(Callback<OriginalCbFnT> originalCb)
: originalCallback(std::move(originalCb))
{}
/** EXPLANATION:
@@ -65,7 +68,7 @@ public:
}
public:
OriginalCbFnT originalCbFn;
Callback<OriginalCbFnT> originalCallback;
std::exception_ptr exception;
};
@@ -84,8 +87,9 @@ class NonPostedAsynchronousContinuation
: public AsynchronousContinuation<OriginalCbFnT>
{
public:
explicit NonPostedAsynchronousContinuation(OriginalCbFnT originalCbFn)
: AsynchronousContinuation<OriginalCbFnT>(originalCbFn)
explicit NonPostedAsynchronousContinuation(
Callback<OriginalCbFnT> originalCb)
: AsynchronousContinuation<OriginalCbFnT>(originalCb)
{}
/**
@@ -100,10 +104,11 @@ public:
template<typename... Args>
void callOriginalCb(Args&&... args)
{
if (AsynchronousContinuation<OriginalCbFnT>::originalCbFn)
if (AsynchronousContinuation<OriginalCbFnT>::originalCallback
.callbackFn)
{
AsynchronousContinuation<OriginalCbFnT>::originalCbFn(
std::forward<Args>(args)...);
AsynchronousContinuation<OriginalCbFnT>::originalCallback
.callbackFn(std::forward<Args>(args)...);
}
}
};
@@ -115,7 +120,7 @@ class PostedAsynchronousContinuation
public:
PostedAsynchronousContinuation(
const std::shared_ptr<ComponentThread> &caller,
OriginalCbFnT originalCbFn)
Callback<OriginalCbFnT> originalCbFn)
: AsynchronousContinuation<OriginalCbFnT>(originalCbFn),
caller(caller)
{}
@@ -123,11 +128,13 @@ public:
template<typename... Args>
void callOriginalCb(Args&&... args)
{
if (AsynchronousContinuation<OriginalCbFnT>::originalCbFn)
if (AsynchronousContinuation<OriginalCbFnT>::originalCallback
.callbackFn)
{
caller->getIoService().post(
std::bind(
AsynchronousContinuation<OriginalCbFnT>::originalCbFn,
AsynchronousContinuation<OriginalCbFnT>::originalCallback
.callbackFn,
std::forward<Args>(args)...));
}
}
@@ -0,0 +1,25 @@
#ifndef ASYNCHRONOUS_CONTINUATION_CHAIN_LINK_H
#define ASYNCHRONOUS_CONTINUATION_CHAIN_LINK_H
#include <memory>
namespace smo {
/**
* @brief Base class for all asynchronous continuation chain links
*
* This non-template base class provides type erasure for the continuation
* chain, allowing RTTI and dynamic casting when walking the chain.
*
* The chain walking logic can use dynamic_cast to determine the most
* derived type and perform appropriate operations.
*/
class AsynchronousContinuationChainLink
{
public:
virtual ~AsynchronousContinuationChainLink() = default;
};
} // namespace smo
#endif // ASYNCHRONOUS_CONTINUATION_CHAIN_LINK_H
+6 -13
View File
@@ -7,7 +7,7 @@
namespace smo {
// Forward declaration
class AsyncContinuation;
class AsynchronousContinuationChainLink;
/**
* @brief Callback class that wraps a function and its caller continuation
@@ -15,23 +15,16 @@ class AsyncContinuation;
* This class provides a way to pass both a callback function and the
* caller's continuation in a single object, enabling deadlock detection
* by walking the chain of continuations.
*
* Usage: Callback<CbFnT>{context, std::bind(...)}
*/
template<typename CbFnT>
class Callback
{
public:
/**
* @brief Constructor
* @param caller The caller's continuation
* @param cb The callback function to invoke
*/
Callback(std::shared_ptr<AsyncContinuation> caller, std::function<CbFnT> cb)
: callerContinuation(std::move(caller)), callback(std::move(cb))
{}
public:
std::shared_ptr<AsyncContinuation> callerContinuation;
std::function<CbFnT> callback;
// Aggregate initialization allows: Callback<CbFnT>{context, std::bind(...)}
std::shared_ptr<AsynchronousContinuationChainLink> callerContinuation;
CbFnT callbackFn;
};
} // namespace smo
+2 -1
View File
@@ -11,6 +11,7 @@
#include <lockSet.h>
#include <asynchronousContinuation.h>
#include <lockerAndInvokerBase.h>
#include <callback.h>
namespace smo {
@@ -21,7 +22,7 @@ class SerializedAsynchronousContinuation
public:
SerializedAsynchronousContinuation(
const std::shared_ptr<ComponentThread> &caller,
OriginalCbFnT originalCbFn,
Callback<OriginalCbFnT> originalCbFn,
std::vector<std::reference_wrapper<SpinLock>> requiredLocks = {})
: PostedAsynchronousContinuation<OriginalCbFnT>(caller, originalCbFn),
requiredLocks(*this, std::move(requiredLocks))
+3 -2
View File
@@ -8,6 +8,7 @@
#include <preprocessor.h>
#include <componentThread.h>
#include <user/deviceAttachmentSpec.h>
#include <callback.h>
namespace smo {
namespace sense_api {
@@ -44,10 +45,10 @@ typedef int (sal_mlo_finalizeIndFn)(void);
typedef void (sal_mlo_attachDeviceReqFn)(
const std::shared_ptr<device::DeviceAttachmentSpec>& desc,
const std::shared_ptr<ComponentThread>& componentThread,
sal_mlo_attachDeviceReqCbFn cb);
Callback<sal_mlo_attachDeviceReqCbFn> cb);
typedef void (sal_mlo_detachDeviceReqFn)(
const std::shared_ptr<device::DeviceAttachmentSpec>& desc,
sal_mlo_detachDeviceReqCbFn cb);
Callback<sal_mlo_detachDeviceReqCbFn> cb);
/**
* @brief Hooks provided by Salmanoff to senseApi libraries.
+120 -65
View File
@@ -9,8 +9,10 @@
#include <opts.h>
#include <user/senseApiDesc.h>
#include <user/deviceAttachmentSpec.h>
#include <callback.h>
#include <livoxProto1/livoxProto1.h>
#include <livoxProto1/device.h>
#include <asynchronousContinuation.h>
namespace smo {
@@ -50,6 +52,105 @@ static LivoxProto1DllState livoxProto1;
// Attached Livox devices
static std::vector<std::shared_ptr<livoxProto1::Device>> g_attachedDevices;
// Continuation classes for async operations
class AttachDeviceReq
: public smo::NonPostedAsynchronousContinuation<sal_mlo_attachDeviceReqCbFn>
{
public:
AttachDeviceReq(
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec,
smo::Callback<sal_mlo_attachDeviceReqCbFn> cb)
: smo::NonPostedAsynchronousContinuation<sal_mlo_attachDeviceReqCbFn>(
std::move(cb)),
spec(spec)
{}
public:
const std::shared_ptr<smo::device::DeviceAttachmentSpec> spec;
public:
void attachDeviceReq1(
std::shared_ptr<AttachDeviceReq> context,
bool success, std::shared_ptr<livoxProto1::Device> dev)
{
if (!dev)
{
std::cerr << __func__ << ": Failed to create Livox device: "
<< context->spec->deviceSelector << std::endl;
context->callOriginalCb(false, context->spec);
return;
}
g_attachedDevices.push_back(dev);
if (1 || OptionParser::getOptions().verbose)
{
std::cout << __func__ << ": Successfully attached Livox "
"device: " << context->spec->deviceSelector << " (ID: "
<< context->spec->deviceIdentifier << ")\n";
}
context->callOriginalCb(success, context->spec);
}
};
class DetachDeviceReq
: public smo::NonPostedAsynchronousContinuation<sal_mlo_detachDeviceReqCbFn>
{
public:
DetachDeviceReq(
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec,
smo::Callback<sal_mlo_detachDeviceReqCbFn> cb)
: smo::NonPostedAsynchronousContinuation<sal_mlo_detachDeviceReqCbFn>(
std::move(cb)),
spec(spec)
{}
public:
const std::shared_ptr<smo::device::DeviceAttachmentSpec> spec;
public:
void detachDeviceReq1(
std::shared_ptr<DetachDeviceReq> context,
bool success)
{
if (!success)
{
std::cerr << __func__ << ": Failed to destroy Livox device: "
<< context->spec->deviceIdentifier << "\n";
context->callOriginalCb(false, context->spec);
return;
}
// Find the device in g_attachedDevices and remove it.
auto eraseIt = std::find_if(
g_attachedDevices.begin(), g_attachedDevices.end(),
[context](const std::shared_ptr<livoxProto1::Device>& dev)
{
const std::string& devId = dev->discoveredDevice.deviceIdentifier;
std::string devIdPrefix = devId.substr(
0, std::min<size_t>(14, devId.size()));
return devIdPrefix == context->spec->deviceSelector.substr(
0, std::min<size_t>(14, context->spec->deviceSelector.size()));
}
);
if (eraseIt == g_attachedDevices.end())
{
std::cerr << __func__ << ": Race condition: device not found "
"in g_attachedDevices for detachment: "
<< context->spec->deviceIdentifier << "\n";
context->callOriginalCb(false, context->spec);
return;
}
g_attachedDevices.erase(eraseIt);
std::cout << __func__ << ": Successfully detached Livox device: "
<< context->spec->deviceIdentifier << "\n";
context->callOriginalCb(success, context->spec);
}
};
// Callback function declarations
extern "C" sal_mlo_initializeIndFn livoxGen1_initializeInd;
extern "C" sal_mlo_finalizeIndFn livoxGen1_finalizeInd;
@@ -152,7 +253,7 @@ extern "C" int livoxGen1_finalizeInd(void)
extern "C" void livoxGen1_attachDeviceReq(
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& desc,
const std::shared_ptr<smo::ComponentThread>& componentThread,
smo::sense_api::sal_mlo_attachDeviceReqCbFn cb
Callback<smo::sense_api::sal_mlo_attachDeviceReqCbFn> cb
)
{
if (!livoxProto1.livoxProto1_getOrCreateDeviceReq)
@@ -170,7 +271,10 @@ extern "C" void livoxGen1_attachDeviceReq(
for (const auto& dev : g_attachedDevices)
{
if (dev->discoveredDevice.deviceIdentifier == desc->deviceIdentifier)
{ return; }
{
cb.callbackFn(true, desc);
return;
}
}
// Parse integer parameters from provider params with defaults
@@ -245,39 +349,23 @@ extern "C" void livoxGen1_attachDeviceReq(
}
}
auto request = std::make_shared<AttachDeviceReq>(desc, cb);
(*livoxProto1.livoxProto1_getOrCreateDeviceReq)(
desc->deviceSelector, // deviceIdentifier (broadcast code)
componentThread,
handshakeTimeoutMs, retryDelayMs,
smoIp, smoSubnetNbits,
dataPort, cmdPort, imuPort,
[desc, cb](
bool success, std::shared_ptr<livoxProto1::Device> dev) -> void
{
if (!dev)
{
std::cerr << __func__ << ": Failed to create Livox device: "
<< desc->deviceSelector << std::endl;
cb(false, desc);
return;
}
g_attachedDevices.push_back(dev);
if (1 || OptionParser::getOptions().verbose)
{
std::cout << __func__ << ": Successfully attached Livox "
"device: " << desc->deviceSelector << " (ID: "
<< desc->deviceIdentifier << ")\n";
}
cb(success, desc);
}
);
{request, std::bind(
&AttachDeviceReq::attachDeviceReq1,
request.get(), request,
std::placeholders::_1, std::placeholders::_2)});
}
extern "C" void livoxGen1_detachDeviceReq(
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& desc,
smo::sense_api::sal_mlo_detachDeviceReqCbFn cb
Callback<smo::sense_api::sal_mlo_detachDeviceReqCbFn> cb
)
{
/** FIXME:
@@ -307,51 +395,18 @@ extern "C" void livoxGen1_detachDeviceReq(
std::cerr << std::string(__func__)
<< ": Device not found for detachment: "
<< desc->deviceIdentifier << std::endl;
cb(false, desc);
cb.callbackFn(false, desc);
return;
}
auto request = std::make_shared<DetachDeviceReq>(desc, cb);
(*livoxProto1.livoxProto1_destroyDeviceReq)(
*it,
[cb, desc](bool success)
{
if (!success)
{
std::cerr << __func__ << ": Failed to destroy Livox device: "
<< desc->deviceIdentifier << "\n";
cb(false, desc);
return;
}
// Find the device in g_attachedDevices and remove it.
auto eraseIt = std::find_if(
g_attachedDevices.begin(), g_attachedDevices.end(),
[desc](const std::shared_ptr<livoxProto1::Device>& dev)
{
const std::string& devId = dev->discoveredDevice.deviceIdentifier;
std::string devIdPrefix = devId.substr(
0, std::min<size_t>(14, devId.size()));
return devIdPrefix == desc->deviceSelector.substr(
0, std::min<size_t>(14, desc->deviceSelector.size()));
}
);
if (eraseIt == g_attachedDevices.end())
{
std::cerr << __func__ << ": Race condition: device not found "
"in g_attachedDevices for detachment: "
<< desc->deviceIdentifier << "\n";
cb(false, desc);
return;
}
g_attachedDevices.erase(eraseIt);
std::cout << __func__ << ": Successfully detached Livox device: "
<< desc->deviceIdentifier << "\n";
cb(success, desc);
}
);
{request, std::bind(
&DetachDeviceReq::detachDeviceReq1,
request.get(), request,
std::placeholders::_1)});
}
// Exported function
+6 -5
View File
@@ -8,6 +8,7 @@
#include <xcb/xcb.h>
#include <user/senseApiDesc.h>
#include <user/deviceAttachmentSpec.h>
#include <callback.h>
#include <xcbXorg/xcbXorg.h>
#include "xcbWindow.h"
@@ -276,7 +277,7 @@ static int xcbWindow_finalizeInd(void)
static void xcbWindow_attachDeviceReq(
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& desc,
const std::shared_ptr<smo::ComponentThread>& componentThread,
smo::sense_api::sal_mlo_attachDeviceReqCbFn cb
smo::Callback<smo::sense_api::sal_mlo_attachDeviceReqCbFn> cb
)
{
// Not used yet, but may be used later.
@@ -289,12 +290,12 @@ static void xcbWindow_attachDeviceReq(
<< g_attachedWindows.back()->stringify()
<< "\n";
cb(true, desc);
cb.callbackFn(true, desc);
}
static void xcbWindow_detachDeviceReq(
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec,
smo::sense_api::sal_mlo_detachDeviceReqCbFn cb
smo::Callback<smo::sense_api::sal_mlo_detachDeviceReqCbFn> cb
)
{
auto it = std::find_if(g_attachedWindows.begin(), g_attachedWindows.end(),
@@ -308,7 +309,7 @@ static void xcbWindow_detachDeviceReq(
std::cerr << __func__ << ": Device not found for detachment:\n"
<< spec->stringify() << "\n";
cb(false, spec);
cb.callbackFn(false, spec);
return;
}
@@ -316,7 +317,7 @@ static void xcbWindow_detachDeviceReq(
std::cout << __func__ << ": Detached X11 window device:\n"
<< spec->stringify() << "\n";
cb(true, spec);
cb.callbackFn(true, spec);
}
// SenseApi descriptor
+10 -9
View File
@@ -2,6 +2,7 @@
#include <opts.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <body/body.h>
#include <componentThread.h>
#include <mind.h>
@@ -21,7 +22,7 @@ class Body::InitializeReq
public:
InitializeReq(
Mind &parent, const std::shared_ptr<ComponentThread> &caller,
bodyLifetimeMgmtOpCbFn callback)
Callback<bodyLifetimeMgmtOpCbFn> callback)
: PostedAsynchronousContinuation<bodyLifetimeMgmtOpCbFn>(caller, callback),
parent(parent)
{}
@@ -78,10 +79,10 @@ public:
}
sense_api::SenseApiManager::getInstance()
.attachAllSenseDevicesFromSpecsReq(
std::bind(
{context, std::bind(
&InitializeReq::initializeReq2,
context.get(), context,
std::placeholders::_1));
std::placeholders::_1)});
}
void initializeReq2(
@@ -117,10 +118,10 @@ public:
std::cout << "Mrntt: About to detach all sense devices." << "\n";
sense_api::SenseApiManager::getInstance().detachAllSenseDevicesReq(
std::bind(
{context, std::bind(
&FinalizeReq::finalizeReq2,
context.get(), context,
std::placeholders::_1));
std::placeholders::_1)});
}
void finalizeReq2(
@@ -141,7 +142,7 @@ public:
}
};
void Body::initializeReq(bodyLifetimeMgmtOpCbFn callback)
void Body::initializeReq(Callback<bodyLifetimeMgmtOpCbFn> callback)
{
auto mrntt = ComponentThread::getSelf();
@@ -160,7 +161,7 @@ void Body::initializeReq(bodyLifetimeMgmtOpCbFn callback)
request.get(), request));
}
void Body::finalizeReq(bodyLifetimeMgmtOpCbFn callback)
void Body::finalizeReq(Callback<bodyLifetimeMgmtOpCbFn> callback)
{
auto mrntt = ComponentThread::getSelf();
@@ -168,7 +169,7 @@ void Body::finalizeReq(bodyLifetimeMgmtOpCbFn callback)
{
std::cerr << __func__ << ": Must be invoked by Mrntt thread"
<< std::endl;
callback(false);
callback.callbackFn(false);
return;
}
@@ -176,7 +177,7 @@ void Body::finalizeReq(bodyLifetimeMgmtOpCbFn callback)
{
std::cout << "Mrntt: Body component not initialized. "
<< "Skipping finalization." << "\n";
callback(true);
callback.callbackFn(true);
return;
}
+9 -8
View File
@@ -5,6 +5,7 @@
#include <boost/asio.hpp>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <callback.h>
#include <mind.h>
#include <mindManager/mindManager.h>
#include <componentThread.h>
@@ -96,8 +97,8 @@ void MindThread::main(MindThread& self)
if (sendExceptionInd)
{
mrntt::mrntt.finalizeReq(
std::bind(
&mrntt::marionetteFinalizeReqCb, std::placeholders::_1));
{nullptr, std::bind(
&mrntt::marionetteFinalizeReqCb, std::placeholders::_1)});
}
}
@@ -111,7 +112,7 @@ public:
ThreadLifetimeMgmtOp(
const std::shared_ptr<ComponentThread> &caller,
const std::shared_ptr<MindThread> &target,
threadLifetimeMgmtOpCbFn callback)
Callback<threadLifetimeMgmtOpCbFn> callback)
: PostedAsynchronousContinuation<threadLifetimeMgmtOpCbFn>(
caller, callback),
target(target)
@@ -205,7 +206,7 @@ void ComponentThread::cleanup(void)
this->keepLooping = false;
}
void MindThread::joltThreadReq(threadLifetimeMgmtOpCbFn callback)
void MindThread::joltThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
/** EXPLANATION:
* We can't use shared_from_this() here because JOLTing occurs prior to
@@ -241,7 +242,7 @@ void MindThread::joltThreadReq(threadLifetimeMgmtOpCbFn callback)
}
// Thread management method implementations
void MindThread::startThreadReq(threadLifetimeMgmtOpCbFn callback)
void MindThread::startThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
@@ -253,7 +254,7 @@ void MindThread::startThreadReq(threadLifetimeMgmtOpCbFn callback)
request.get(), request));
}
void MindThread::exitThreadReq(threadLifetimeMgmtOpCbFn callback)
void MindThread::exitThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
@@ -270,7 +271,7 @@ void MindThread::exitThreadReq(threadLifetimeMgmtOpCbFn callback)
request.get(), request));
}
void MindThread::pauseThreadReq(threadLifetimeMgmtOpCbFn callback)
void MindThread::pauseThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
if (id == ComponentThread::MRNTT)
{
@@ -288,7 +289,7 @@ void MindThread::pauseThreadReq(threadLifetimeMgmtOpCbFn callback)
request.get(), request));
}
void MindThread::resumeThreadReq(threadLifetimeMgmtOpCbFn callback)
void MindThread::resumeThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
if (id == ComponentThread::MRNTT)
{
+6 -5
View File
@@ -7,6 +7,7 @@
#include <memory>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <callback.h>
#include <deviceManager/deviceManager.h>
#include <senseApis/senseApiManager.h>
#include <marionette/marionette.h>
@@ -45,7 +46,7 @@ public:
NewDeviceAttachmentSpecInd(
std::shared_ptr<DeviceAttachmentSpec> s,
const std::shared_ptr<ComponentThread> &caller,
newDeviceAttachmentSpecIndCbFn cb)
Callback<newDeviceAttachmentSpecIndCbFn> cb)
: PostedAsynchronousContinuation<newDeviceAttachmentSpecIndCbFn>(
caller, cb),
spec(s)
@@ -61,10 +62,10 @@ public:
{
sense_api::SenseApiManager::getInstance().attachSenseDeviceReq(
spec,
std::bind(
{context, std::bind(
&NewDeviceAttachmentSpecInd::newDeviceAttachmentSpecInd2,
context.get(), context,
std::placeholders::_1, std::placeholders::_2));
std::placeholders::_1, std::placeholders::_2)});
}
void newDeviceAttachmentSpecInd2(
@@ -125,14 +126,14 @@ public:
void DeviceManager::newDeviceAttachmentSpecInd(
std::shared_ptr<DeviceAttachmentSpec> spec,
newDeviceAttachmentSpecIndCbFn callback)
Callback<newDeviceAttachmentSpecIndCbFn> callback)
{
// Check if a DeviceAttachmentSpec already matches
for (const auto& existingSpec : deviceAttachmentSpecs)
{
if (!(*existingSpec == *spec)) { continue; }
// Already exists, callback with error
callback(false, nullptr, spec);
callback.callbackFn(false, nullptr, spec);
return;
}
+3 -2
View File
@@ -3,6 +3,7 @@
#include <component.h>
#include <functional>
#include <callback.h>
namespace smo {
@@ -19,8 +20,8 @@ public:
~Body() = default;
typedef std::function<void(bool)> bodyLifetimeMgmtOpCbFn;
void initializeReq(bodyLifetimeMgmtOpCbFn callback);
void finalizeReq(bodyLifetimeMgmtOpCbFn callback);
void initializeReq(Callback<bodyLifetimeMgmtOpCbFn> callback);
void finalizeReq(Callback<bodyLifetimeMgmtOpCbFn> callback);
private:
class InitializeReq;
+3 -2
View File
@@ -4,6 +4,7 @@
#include <config.h>
#include <memory>
#include <functional>
#include <callback.h>
namespace smo {
@@ -44,8 +45,8 @@ public:
public:
typedef std::function<void(bool)> mrnttLifetimeMgmtOpCbFn;
void initializeReq(mrnttLifetimeMgmtOpCbFn callback);
void finalizeReq(mrnttLifetimeMgmtOpCbFn callback);
void initializeReq(Callback<mrnttLifetimeMgmtOpCbFn> callback);
void finalizeReq(Callback<mrnttLifetimeMgmtOpCbFn> callback);
private:
class MrnttLifetimeMgmtOp;
+6 -5
View File
@@ -12,6 +12,7 @@
#include <sched.h>
#include <unistd.h>
#include <memory>
#include <callback.h>
namespace smo {
@@ -137,10 +138,10 @@ public:
// Thread management methods
typedef std::function<void()> threadLifetimeMgmtOpCbFn;
void startThreadReq(threadLifetimeMgmtOpCbFn callback);
void exitThreadReq(threadLifetimeMgmtOpCbFn callback);
void pauseThreadReq(threadLifetimeMgmtOpCbFn callback);
void resumeThreadReq(threadLifetimeMgmtOpCbFn callback);
void startThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void exitThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void pauseThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void resumeThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
/**
* JOLTs this thread to begin processing after global initialization.
@@ -149,7 +150,7 @@ public:
* event loops and set up TLS vars after all global constructors have
* completed. This prevents race conditions during system startup.
*/
void joltThreadReq(threadLifetimeMgmtOpCbFn callback);
void joltThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
// CPU management methods
void pinToCpu(int cpuId);
@@ -10,6 +10,7 @@
#include <functional>
#include <user/deviceAttachmentSpec.h>
#include <deviceManager/device.h>
#include <callback.h>
namespace smo {
namespace device {
@@ -41,7 +42,7 @@ public:
newDeviceAttachmentSpecIndCbFn;
void newDeviceAttachmentSpecInd(
std::shared_ptr<DeviceAttachmentSpec> spec,
newDeviceAttachmentSpecIndCbFn callback);
Callback<newDeviceAttachmentSpecIndCbFn> callback);
private:
DeviceManager() = default;
+11 -7
View File
@@ -7,6 +7,7 @@
#include <memory>
#include <unordered_map>
#include <string>
#include <callback.h>
#include <component.h>
#include <componentThread.h>
@@ -23,8 +24,8 @@ public:
~Mind(void) = default;
typedef std::function<void(bool)> mindLifetimeMgmtOpCbFn;
void initializeReq(mindLifetimeMgmtOpCbFn callback);
void finalizeReq(mindLifetimeMgmtOpCbFn callback);
void initializeReq(Callback<mindLifetimeMgmtOpCbFn> callback);
void finalizeReq(Callback<mindLifetimeMgmtOpCbFn> callback);
// ComponentThread access methods
std::shared_ptr<MindThread> getComponentThread(
@@ -36,11 +37,14 @@ public:
// Thread management methods (moved from ComponentThread)
typedef std::function<void()> mindThreadLifetimeMgmtOpCbFn;
void joltAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
void startAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
void pauseAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
void resumeAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
void exitAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
void joltAllMindThreadsReq(Callback<mindThreadLifetimeMgmtOpCbFn> callback);
void startAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback);
void pauseAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback);
void resumeAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback);
void exitAllMindThreadsReq(Callback<mindThreadLifetimeMgmtOpCbFn> callback);
// CPU distribution method
void distributeAndPinThreadsAcrossCpus();
+5 -4
View File
@@ -11,6 +11,7 @@
#include <asynchronousLoop.h>
#include <senseApis/senseApiLib.h>
#include <user/deviceAttachmentSpec.h>
#include <callback.h>
namespace smo {
namespace sense_api {
@@ -54,10 +55,10 @@ public:
void attachSenseDeviceReq(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec,
attachSenseDeviceReqCbFn cb);
Callback<attachSenseDeviceReqCbFn> cb);
void detachSenseDeviceReq(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec,
detachSenseDeviceReqCbFn cb);
Callback<detachSenseDeviceReqCbFn> cb);
typedef std::function<void(AsynchronousLoop &results)>
attachAllSenseDevicesFromSpecsReqCbFn;
@@ -65,9 +66,9 @@ public:
detachAllSenseDevicesReqCbFn;
void attachAllSenseDevicesFromSpecsReq(
attachAllSenseDevicesFromSpecsReqCbFn cb);
Callback<attachAllSenseDevicesFromSpecsReqCbFn> cb);
void detachAllSenseDevicesReq(
detachAllSenseDevicesReqCbFn cb);
Callback<detachAllSenseDevicesReqCbFn> cb);
std::string stringifyLibs() const;
+12 -11
View File
@@ -1,6 +1,7 @@
#include <iostream>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <component.h>
#include <componentThread.h>
#include <mindManager/mindManager.h>
@@ -15,7 +16,7 @@ class MarionetteComponent::MrnttLifetimeMgmtOp
public:
MrnttLifetimeMgmtOp(
MarionetteComponent &parent, const std::shared_ptr<ComponentThread> &caller,
mrnttLifetimeMgmtOpCbFn callback)
Callback<mrnttLifetimeMgmtOpCbFn> callback)
: PostedAsynchronousContinuation<mrnttLifetimeMgmtOpCbFn>(
caller, callback),
parent(parent)
@@ -37,10 +38,9 @@ public:
}
smo::mind::globalMind = std::make_shared<Mind>();
smo::mind::globalMind->initializeReq(
std::bind(
&MrnttLifetimeMgmtOp::initializeReq2,
this, context, std::placeholders::_1));
smo::mind::globalMind->initializeReq({context, std::bind(
&MrnttLifetimeMgmtOp::initializeReq2,
this, context, std::placeholders::_1)});
}
void initializeReq2(
@@ -70,10 +70,9 @@ public:
+ ": Must be executed on Marionette thread");
}
smo::mind::globalMind->finalizeReq(
std::bind(
&MrnttLifetimeMgmtOp::finalizeReq2,
this, context, std::placeholders::_1));
smo::mind::globalMind->finalizeReq({context, std::bind(
&MrnttLifetimeMgmtOp::finalizeReq2,
this, context, std::placeholders::_1)});
}
void finalizeReq2(
@@ -93,7 +92,8 @@ public:
}
};
void MarionetteComponent::initializeReq(mrnttLifetimeMgmtOpCbFn callback)
void MarionetteComponent::initializeReq(
Callback<mrnttLifetimeMgmtOpCbFn> callback)
{
auto mrntt = ComponentThread::getSelf();
@@ -112,7 +112,8 @@ void MarionetteComponent::initializeReq(mrnttLifetimeMgmtOpCbFn callback)
request.get(), request));
}
void MarionetteComponent::finalizeReq(mrnttLifetimeMgmtOpCbFn callback)
void MarionetteComponent::finalizeReq(
Callback<mrnttLifetimeMgmtOpCbFn> callback)
{
auto mrntt = ComponentThread::getSelf();
+11 -15
View File
@@ -56,10 +56,9 @@ void marionetteInitializeReqCb(bool success)
std::cerr << __func__ << ": Failed to initialize Marionette. Shutting down."
<< '\n';
mrntt::mrntt.finalizeReq(
std::bind(
&mrntt::marionetteFinalizeReqCb,
std::placeholders::_1));
mrntt::mrntt.finalizeReq({nullptr, std::bind(
&mrntt::marionetteFinalizeReqCb,
std::placeholders::_1)});
}
} // namespace mrntt
@@ -92,10 +91,9 @@ void MarionetteThread::main(MarionetteThread& self)
default:
break;
}
mrntt::mrntt.finalizeReq(
std::bind(
&mrntt::marionetteFinalizeReqCb,
std::placeholders::_1));
mrntt::mrntt.finalizeReq({nullptr, std::bind(
&mrntt::marionetteFinalizeReqCb,
std::placeholders::_1)});
}
);
@@ -137,9 +135,8 @@ void MarionetteThread::main(MarionetteThread& self)
callShutdownSalmanoff = true;
// Create new Mind instance just before initializeReq
mrntt::mrntt.initializeReq(
std::bind(
&mrntt::marionetteInitializeReqCb, std::placeholders::_1));
mrntt::mrntt.initializeReq({nullptr, std::bind(
&mrntt::marionetteInitializeReqCb, std::placeholders::_1)});
std::cout << __func__ << ": Entering event loop" << "\n";
@@ -183,10 +180,9 @@ void MarionetteThread::main(MarionetteThread& self)
if (sendExceptionInd)
{
mrntt::exitCode = EXIT_FAILURE;
mrntt::mrntt.finalizeReq(
std::bind(
&mrntt::marionetteFinalizeReqCb,
std::placeholders::_1));
mrntt::mrntt.finalizeReq({nullptr, std::bind(
&mrntt::marionetteFinalizeReqCb,
std::placeholders::_1)});
}
}
+53 -42
View File
@@ -2,6 +2,7 @@
#include <opts.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <mind.h>
#include <componentThread.h>
#include <director/director.h>
@@ -89,7 +90,7 @@ class Mind::MindLifetimeMgmtOp
public:
MindLifetimeMgmtOp(
Mind &parent, const std::shared_ptr<ComponentThread> &caller,
mindLifetimeMgmtOpCbFn callback)
Callback<mindLifetimeMgmtOpCbFn> callback)
: PostedAsynchronousContinuation<mindLifetimeMgmtOpCbFn>(
caller, callback),
parent(parent)
@@ -105,9 +106,9 @@ public:
{
/* Jolt the threads, then start them */
parent.joltAllMindThreadsReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::initializeReq2,
context.get(), context));
context.get(), context)});
}
void initializeReq2(
@@ -117,9 +118,9 @@ public:
std::cout << "Mrntt: All mind threads JOLTed." << "\n";
parent.startAllMindThreadsReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::initializeReq3,
context.get(), context));
context.get(), context)});
}
void initializeReq3(
@@ -129,9 +130,9 @@ public:
std::cout << "Mrntt: All mind threads started." << "\n";
parent.body.initializeReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::initializeReq4,
context.get(), context, std::placeholders::_1));
context.get(), context, std::placeholders::_1)});
}
void initializeReq4(
@@ -148,9 +149,9 @@ public:
)
{
parent.body.finalizeReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::finalizeReq2,
context.get(), context, std::placeholders::_1));
context.get(), context, std::placeholders::_1)});
}
void finalizeReq2(
@@ -169,9 +170,9 @@ public:
* messages from mrntt after processing the exit request.
*/
parent.joltAllMindThreadsReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::finalizeReq3,
context.get(), context));
context.get(), context)});
}
void finalizeReq3(
@@ -181,9 +182,9 @@ public:
std::cout << "Mrntt: All mind threads JOLTed for finalization." << "\n";
parent.exitAllMindThreadsReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::finalizeReq4,
context.get(), context));
context.get(), context)});
}
void finalizeReq4(
@@ -195,7 +196,7 @@ public:
}
};
void Mind::initializeReq(mindLifetimeMgmtOpCbFn callback)
void Mind::initializeReq(Callback<mindLifetimeMgmtOpCbFn> callback)
{
/* Distribute threads across available CPUs */
try
@@ -219,7 +220,7 @@ void Mind::initializeReq(mindLifetimeMgmtOpCbFn callback)
request.get(), request));
}
void Mind::finalizeReq(mindLifetimeMgmtOpCbFn callback)
void Mind::finalizeReq(Callback<mindLifetimeMgmtOpCbFn> callback)
{
const auto& caller = ComponentThread::getSelf();
auto request = std::make_shared<MindLifetimeMgmtOp>(
@@ -258,7 +259,7 @@ class Mind::MindThreadLifetimeMgmtOp
public:
MindThreadLifetimeMgmtOp(
Mind &parent,unsigned int nThreads,
mindThreadLifetimeMgmtOpCbFn callback)
Callback<mindThreadLifetimeMgmtOpCbFn> callback)
: NonPostedAsynchronousContinuation<mindThreadLifetimeMgmtOpCbFn>(callback),
loop(nThreads),
parent(parent)
@@ -311,21 +312,23 @@ public:
}
};
void Mind::joltAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::joltAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
if (threadsHaveBeenJolted)
{
std::cout << "Mrntt: All mind threads already JOLTed. "
<< "Skipping JOLT request." << "\n";
callback();
callback.callbackFn();
return;
}
// If no threads, set flag and call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
threadsHaveBeenJolted = true;
callback();
callback.callbackFn();
return;
}
@@ -336,19 +339,21 @@ void Mind::joltAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->joltThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::joltAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
// Thread management methods (moved from ComponentThread)
void Mind::startAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::startAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
// If no threads, call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
callback();
callback.callbackFn();
return;
}
@@ -359,18 +364,20 @@ void Mind::startAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->startThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
void Mind::pauseAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::pauseAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
// If no threads, call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
callback();
callback.callbackFn();
return;
}
@@ -381,18 +388,20 @@ void Mind::pauseAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->pauseThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
void Mind::resumeAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::resumeAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
// If no threads, call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
callback();
callback.callbackFn();
return;
}
@@ -403,18 +412,20 @@ void Mind::resumeAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->resumeThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
void Mind::exitAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::exitAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
// If no threads, call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
callback();
callback.callbackFn();
return;
}
@@ -425,9 +436,9 @@ void Mind::exitAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->exitThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
+17 -16
View File
@@ -8,6 +8,7 @@
#include <asynchronousBridge.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <user/senseApiDesc.h>
#include <mind.h>
#include <deviceManager/deviceManager.h>
@@ -268,7 +269,7 @@ public:
AttachSenseDeviceReq(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec,
const std::shared_ptr<ComponentThread> &caller,
attachSenseDeviceReqCbFn cb)
Callback<attachSenseDeviceReqCbFn> cb)
: PostedAsynchronousContinuation<attachSenseDeviceReqCbFn>(
caller, cb),
spec(spec)
@@ -335,10 +336,10 @@ public:
lib.senseApiDesc.sal_mgmt_libOps.attachDeviceReq(
spec, threadForAttachment,
std::bind(
{context, std::bind(
&AttachSenseDeviceReq::attachSenseDeviceReq2,
context.get(), context,
std::placeholders::_1, std::placeholders::_2));
std::placeholders::_1, std::placeholders::_2)});
}
void attachSenseDeviceReq2(
@@ -386,10 +387,10 @@ public:
}
lib.senseApiDesc.sal_mgmt_libOps.detachDeviceReq(
spec,
std::bind(
{context, std::bind(
&DetachSenseDeviceReq::detachSenseDeviceReq2,
context.get(), context,
std::placeholders::_1, std::placeholders::_2));
std::placeholders::_1, std::placeholders::_2)});
}
void detachSenseDeviceReq2(
@@ -407,7 +408,7 @@ public:
void SenseApiManager::attachSenseDeviceReq(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec,
attachSenseDeviceReqCbFn cb
Callback<attachSenseDeviceReqCbFn> cb
)
{
const auto& caller = ComponentThread::getSelf();
@@ -422,7 +423,7 @@ void SenseApiManager::attachSenseDeviceReq(
void SenseApiManager::detachSenseDeviceReq(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec,
detachSenseDeviceReqCbFn cb
Callback<detachSenseDeviceReqCbFn> cb
)
{
const auto& caller = ComponentThread::getSelf();
@@ -443,7 +444,7 @@ public:
AttachAllSenseDevicesFromSpecsReq(
const unsigned int totalNSpecs,
const std::shared_ptr<ComponentThread>& caller,
attachAllSenseDevicesFromSpecsReqCbFn cb)
Callback<attachAllSenseDevicesFromSpecsReqCbFn> cb)
: PostedAsynchronousContinuation<attachAllSenseDevicesFromSpecsReqCbFn>(
caller, cb),
loop(totalNSpecs)
@@ -458,10 +459,10 @@ public:
{
SenseApiManager::getInstance().attachSenseDeviceReq(
spec,
std::bind(
{context, std::bind(
&AttachAllSenseDevicesFromSpecsReq::attachAllSenseDevicesFromSpecsReq2,
context.get(), context,
std::placeholders::_1, std::placeholders::_2));
std::placeholders::_1, std::placeholders::_2)});
}
}
@@ -499,13 +500,13 @@ public:
};
void SenseApiManager::attachAllSenseDevicesFromSpecsReq(
attachAllSenseDevicesFromSpecsReqCbFn cb
Callback<attachAllSenseDevicesFromSpecsReqCbFn> cb
)
{
if (device::DeviceManager::getInstance().deviceAttachmentSpecs.size() == 0)
{
AsynchronousLoop tmp(0);
cb(tmp);
cb.callbackFn(tmp);
return;
}
@@ -534,10 +535,10 @@ public:
{
SenseApiManager::getInstance().detachSenseDeviceReq(
spec,
std::bind(
{context, std::bind(
&DetachAllSenseDevicesReq::detachAllSenseDevicesReq2,
context.get(), context,
std::placeholders::_1, std::placeholders::_2));
std::placeholders::_1, std::placeholders::_2)});
}
}
@@ -571,13 +572,13 @@ public:
};
void SenseApiManager::detachAllSenseDevicesReq(
detachAllSenseDevicesReqCbFn cb
Callback<detachAllSenseDevicesReqCbFn> cb
)
{
if (device::DeviceManager::getInstance().deviceAttachmentSpecs.size() == 0)
{
AsynchronousLoop tmp(0);
cb(tmp);
cb.callbackFn(tmp);
return;
}