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:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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(
|
||||
smo::mind::globalMind->initializeReq({context, std::bind(
|
||||
&MrnttLifetimeMgmtOp::initializeReq2,
|
||||
this, context, std::placeholders::_1));
|
||||
this, context, std::placeholders::_1)});
|
||||
}
|
||||
|
||||
void initializeReq2(
|
||||
@@ -70,10 +70,9 @@ public:
|
||||
+ ": Must be executed on Marionette thread");
|
||||
}
|
||||
|
||||
smo::mind::globalMind->finalizeReq(
|
||||
std::bind(
|
||||
smo::mind::globalMind->finalizeReq({context, std::bind(
|
||||
&MrnttLifetimeMgmtOp::finalizeReq2,
|
||||
this, context, std::placeholders::_1));
|
||||
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();
|
||||
|
||||
|
||||
@@ -56,10 +56,9 @@ void marionetteInitializeReqCb(bool success)
|
||||
std::cerr << __func__ << ": Failed to initialize Marionette. Shutting down."
|
||||
<< '\n';
|
||||
|
||||
mrntt::mrntt.finalizeReq(
|
||||
std::bind(
|
||||
mrntt::mrntt.finalizeReq({nullptr, std::bind(
|
||||
&mrntt::marionetteFinalizeReqCb,
|
||||
std::placeholders::_1));
|
||||
std::placeholders::_1)});
|
||||
}
|
||||
|
||||
} // namespace mrntt
|
||||
@@ -92,10 +91,9 @@ void MarionetteThread::main(MarionetteThread& self)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mrntt::mrntt.finalizeReq(
|
||||
std::bind(
|
||||
mrntt::mrntt.finalizeReq({nullptr, std::bind(
|
||||
&mrntt::marionetteFinalizeReqCb,
|
||||
std::placeholders::_1));
|
||||
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::mrntt.finalizeReq({nullptr, std::bind(
|
||||
&mrntt::marionetteFinalizeReqCb,
|
||||
std::placeholders::_1));
|
||||
std::placeholders::_1)});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+53
-42
@@ -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)});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user