diff --git a/commonLibs/livoxProto1/core.cpp b/commonLibs/livoxProto1/core.cpp index 9f09143..6fb0539 100644 --- a/commonLibs/livoxProto1/core.cpp +++ b/commonLibs/livoxProto1/core.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "protocol.h" #include "core.h" @@ -84,7 +85,7 @@ public: GetOrCreateDeviceReq( DeviceManager& mgr, std::shared_ptr device, - livoxProto1_getOrCreateDeviceReqCbFn cb) + smo::Callback 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 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, - livoxProto1_destroyDeviceReqCbFn cb) + smo::Callback cb) : smo::NonPostedAsynchronousContinuation< livoxProto1_destroyDeviceReqCbFn>(std::move(cb)), deviceManager(mgr), pendingDevice(device) @@ -218,7 +219,7 @@ public: void DeviceManager::destroyDeviceReq( std::shared_ptr dev, - livoxProto1_destroyDeviceReqCbFn callback + smo::Callback 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 &componentThread, diff --git a/commonLibs/livoxProto1/core.h b/commonLibs/livoxProto1/core.h index 6fae0de..5ac0677 100644 --- a/commonLibs/livoxProto1/core.h +++ b/commonLibs/livoxProto1/core.h @@ -10,6 +10,7 @@ #include "device.h" #include "broadcastListener.h" #include "livoxProto1.h" +#include 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 callback); void destroyDeviceReq( std::shared_ptr device, - livoxProto1_destroyDeviceReqCbFn callback); + smo::Callback callback); std::optional> getDevice( const std::string &deviceIdentifier); diff --git a/commonLibs/livoxProto1/device.cpp b/commonLibs/livoxProto1/device.cpp index a69657c..18f603b 100644 --- a/commonLibs/livoxProto1/device.cpp +++ b/commonLibs/livoxProto1/device.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "device.h" #include "protocol.h" #include "core.h" @@ -127,7 +128,7 @@ private: std::unique_ptr retryTimer; public: - ConnectReq(Device& dev, Device::connectReqCbFn cb) + ConnectReq(Device& dev, smo::Callback cb) : smo::NonPostedAsynchronousContinuation( 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 callback) { // Create the connection request object to hold state and callbacks auto request = std::make_shared(*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 deviceInfo; - ConnectToKnownDeviceReq(Device& dev, Device::connectToKnownDeviceReqCbFn cb) + ConnectToKnownDeviceReq(Device& dev, smo::Callback cb) : smo::NonPostedAsynchronousContinuation< Device::connectToKnownDeviceReqCbFn>(std::move(cb)), device(dev) {} @@ -297,7 +298,7 @@ public: * broadcastListener. */ void Device::connectToKnownDeviceReq( - Device::connectToKnownDeviceReqCbFn callback + smo::Callback 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 cb) : smo::NonPostedAsynchronousContinuation< Device::connectByDeviceIdentifierReqCbFn>( std::move(cb)), device(dev) @@ -398,7 +399,7 @@ public: }; void Device::connectByDeviceIdentifierReq( - Device::connectByDeviceIdentifierReqCbFn callback + smo::Callback 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 callback); enum class SocketState { @@ -484,7 +486,7 @@ public: public: ExecuteHandshakeReq( Device& dev, const std::string& deviceIP, - Device::executeHandshakeReqCbFn cb) + smo::Callback cb) : smo::NonPostedAsynchronousContinuation( 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 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 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( diff --git a/commonLibs/livoxProto1/device.h b/commonLibs/livoxProto1/device.h index 9f7a494..c4a2f87 100644 --- a/commonLibs/livoxProto1/device.h +++ b/commonLibs/livoxProto1/device.h @@ -13,6 +13,7 @@ #include #include #include "protocol.h" +#include // Forward declaration namespace smo { @@ -111,13 +112,15 @@ public: typedef std::function disconnectReqCbFn; // Async connection methods - void connectReq(connectReqCbFn callback); - void connectToKnownDeviceReq(connectToKnownDeviceReqCbFn callback); + void connectReq(smo::Callback callback); + void connectToKnownDeviceReq( + smo::Callback callback); void connectByDeviceIdentifierReq( - connectByDeviceIdentifierReqCbFn callback); + smo::Callback callback); void executeHandshakeReq( - const std::string& deviceIP, executeHandshakeReqCbFn callback); - void disconnectReq(disconnectReqCbFn callback); + const std::string& deviceIP, + smo::Callback callback); + void disconnectReq(smo::Callback callback); // Heartbeat state std::unique_ptr heartbeatTimer; diff --git a/commonLibs/livoxProto1/livoxProto1.cpp b/commonLibs/livoxProto1/livoxProto1.cpp index e6adc13..553f104 100644 --- a/commonLibs/livoxProto1/livoxProto1.cpp +++ b/commonLibs/livoxProto1/livoxProto1.cpp @@ -1,4 +1,5 @@ #include +#include #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 callback ) { // Get the global DeviceManager instance @@ -35,7 +36,7 @@ void livoxProto1_getOrCreateDeviceReq( void livoxProto1_destroyDeviceReq( std::shared_ptr device, - livoxProto1_destroyDeviceReqCbFn callback + smo::Callback callback ) { auto& protoState = livoxProto1::getProtoState(); diff --git a/commonLibs/livoxProto1/livoxProto1.h b/commonLibs/livoxProto1/livoxProto1.h index 0d75cf0..53015a7 100644 --- a/commonLibs/livoxProto1/livoxProto1.h +++ b/commonLibs/livoxProto1/livoxProto1.h @@ -5,6 +5,7 @@ #include #include #include +#include // 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 callback); typedef std::function livoxProto1_destroyDeviceReqCbFn; typedef void livoxProto1_destroyDeviceReqFn( std::shared_ptr device, - livoxProto1_destroyDeviceReqCbFn callback); + smo::Callback callback); livoxProto1_mainFn livoxProto1_main; diff --git a/include/asynchronousContinuation.h b/include/asynchronousContinuation.h index 407318d..cd76783 100644 --- a/include/asynchronousContinuation.h +++ b/include/asynchronousContinuation.h @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace smo { @@ -21,10 +23,11 @@ namespace smo { */ template class AsynchronousContinuation +: public AsynchronousContinuationChainLink { public: - explicit AsynchronousContinuation(OriginalCbFnT originalCbFn) - : originalCbFn(std::move(originalCbFn)) + explicit AsynchronousContinuation(Callback originalCb) + : originalCallback(std::move(originalCb)) {} /** EXPLANATION: @@ -65,7 +68,7 @@ public: } public: - OriginalCbFnT originalCbFn; + Callback originalCallback; std::exception_ptr exception; }; @@ -84,8 +87,9 @@ class NonPostedAsynchronousContinuation : public AsynchronousContinuation { public: - explicit NonPostedAsynchronousContinuation(OriginalCbFnT originalCbFn) - : AsynchronousContinuation(originalCbFn) + explicit NonPostedAsynchronousContinuation( + Callback originalCb) + : AsynchronousContinuation(originalCb) {} /** @@ -100,10 +104,11 @@ public: template void callOriginalCb(Args&&... args) { - if (AsynchronousContinuation::originalCbFn) + if (AsynchronousContinuation::originalCallback + .callbackFn) { - AsynchronousContinuation::originalCbFn( - std::forward(args)...); + AsynchronousContinuation::originalCallback + .callbackFn(std::forward(args)...); } } }; @@ -115,7 +120,7 @@ class PostedAsynchronousContinuation public: PostedAsynchronousContinuation( const std::shared_ptr &caller, - OriginalCbFnT originalCbFn) + Callback originalCbFn) : AsynchronousContinuation(originalCbFn), caller(caller) {} @@ -123,11 +128,13 @@ public: template void callOriginalCb(Args&&... args) { - if (AsynchronousContinuation::originalCbFn) + if (AsynchronousContinuation::originalCallback + .callbackFn) { caller->getIoService().post( std::bind( - AsynchronousContinuation::originalCbFn, + AsynchronousContinuation::originalCallback + .callbackFn, std::forward(args)...)); } } diff --git a/include/asynchronousContinuationChainLink.h b/include/asynchronousContinuationChainLink.h new file mode 100644 index 0000000..5b5eb0c --- /dev/null +++ b/include/asynchronousContinuationChainLink.h @@ -0,0 +1,25 @@ +#ifndef ASYNCHRONOUS_CONTINUATION_CHAIN_LINK_H +#define ASYNCHRONOUS_CONTINUATION_CHAIN_LINK_H + +#include + +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 diff --git a/include/callback.h b/include/callback.h index 2a6e98c..f86132c 100644 --- a/include/callback.h +++ b/include/callback.h @@ -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{context, std::bind(...)} */ template class Callback { public: - /** - * @brief Constructor - * @param caller The caller's continuation - * @param cb The callback function to invoke - */ - Callback(std::shared_ptr caller, std::function cb) - : callerContinuation(std::move(caller)), callback(std::move(cb)) - {} - -public: - std::shared_ptr callerContinuation; - std::function callback; + // Aggregate initialization allows: Callback{context, std::bind(...)} + std::shared_ptr callerContinuation; + CbFnT callbackFn; }; } // namespace smo diff --git a/include/serializedAsynchronousContinuation.h b/include/serializedAsynchronousContinuation.h index f4a372d..b019e59 100644 --- a/include/serializedAsynchronousContinuation.h +++ b/include/serializedAsynchronousContinuation.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace smo { @@ -21,7 +22,7 @@ class SerializedAsynchronousContinuation public: SerializedAsynchronousContinuation( const std::shared_ptr &caller, - OriginalCbFnT originalCbFn, + Callback originalCbFn, std::vector> requiredLocks = {}) : PostedAsynchronousContinuation(caller, originalCbFn), requiredLocks(*this, std::move(requiredLocks)) diff --git a/include/user/senseApiDesc.h b/include/user/senseApiDesc.h index 52e081c..9d555e6 100644 --- a/include/user/senseApiDesc.h +++ b/include/user/senseApiDesc.h @@ -8,6 +8,7 @@ #include #include #include +#include namespace smo { namespace sense_api { @@ -44,10 +45,10 @@ typedef int (sal_mlo_finalizeIndFn)(void); typedef void (sal_mlo_attachDeviceReqFn)( const std::shared_ptr& desc, const std::shared_ptr& componentThread, - sal_mlo_attachDeviceReqCbFn cb); + Callback cb); typedef void (sal_mlo_detachDeviceReqFn)( const std::shared_ptr& desc, - sal_mlo_detachDeviceReqCbFn cb); + Callback cb); /** * @brief Hooks provided by Salmanoff to senseApi libraries. diff --git a/senseApis/livoxGen1/livoxGen1.cpp b/senseApis/livoxGen1/livoxGen1.cpp index 9eb6836..c4541ff 100644 --- a/senseApis/livoxGen1/livoxGen1.cpp +++ b/senseApis/livoxGen1/livoxGen1.cpp @@ -9,8 +9,10 @@ #include #include #include +#include #include #include +#include namespace smo { @@ -50,6 +52,105 @@ static LivoxProto1DllState livoxProto1; // Attached Livox devices static std::vector> g_attachedDevices; +// Continuation classes for async operations +class AttachDeviceReq +: public smo::NonPostedAsynchronousContinuation +{ +public: + AttachDeviceReq( + const std::shared_ptr& spec, + smo::Callback cb) + : smo::NonPostedAsynchronousContinuation( + std::move(cb)), + spec(spec) + {} + +public: + const std::shared_ptr spec; + +public: + void attachDeviceReq1( + std::shared_ptr context, + bool success, std::shared_ptr 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 +{ +public: + DetachDeviceReq( + const std::shared_ptr& spec, + smo::Callback cb) + : smo::NonPostedAsynchronousContinuation( + std::move(cb)), + spec(spec) + {} + +public: + const std::shared_ptr spec; + +public: + void detachDeviceReq1( + std::shared_ptr 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& dev) + { + const std::string& devId = dev->discoveredDevice.deviceIdentifier; + std::string devIdPrefix = devId.substr( + 0, std::min(14, devId.size())); + return devIdPrefix == context->spec->deviceSelector.substr( + 0, std::min(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& desc, const std::shared_ptr& componentThread, - smo::sense_api::sal_mlo_attachDeviceReqCbFn cb + Callback 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(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 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& desc, - smo::sense_api::sal_mlo_detachDeviceReqCbFn cb + Callback 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(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& dev) - { - const std::string& devId = dev->discoveredDevice.deviceIdentifier; - std::string devIdPrefix = devId.substr( - 0, std::min(14, devId.size())); - return devIdPrefix == desc->deviceSelector.substr( - 0, std::min(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 diff --git a/senseApis/xcbWindow/xcbWindow.cpp b/senseApis/xcbWindow/xcbWindow.cpp index a6ed750..70b92b6 100644 --- a/senseApis/xcbWindow/xcbWindow.cpp +++ b/senseApis/xcbWindow/xcbWindow.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "xcbWindow.h" @@ -276,7 +277,7 @@ static int xcbWindow_finalizeInd(void) static void xcbWindow_attachDeviceReq( const std::shared_ptr& desc, const std::shared_ptr& componentThread, - smo::sense_api::sal_mlo_attachDeviceReqCbFn cb + smo::Callback 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& spec, - smo::sense_api::sal_mlo_detachDeviceReqCbFn cb + smo::Callback 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 diff --git a/smocore/body/body.cpp b/smocore/body/body.cpp index 57f0c12..f536063 100644 --- a/smocore/body/body.cpp +++ b/smocore/body/body.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,7 @@ class Body::InitializeReq public: InitializeReq( Mind &parent, const std::shared_ptr &caller, - bodyLifetimeMgmtOpCbFn callback) + Callback callback) : PostedAsynchronousContinuation(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 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 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; } diff --git a/smocore/componentThread.cpp b/smocore/componentThread.cpp index 5d1bde2..5fab748 100644 --- a/smocore/componentThread.cpp +++ b/smocore/componentThread.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -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 &caller, const std::shared_ptr &target, - threadLifetimeMgmtOpCbFn callback) + Callback callback) : PostedAsynchronousContinuation( caller, callback), target(target) @@ -205,7 +206,7 @@ void ComponentThread::cleanup(void) this->keepLooping = false; } -void MindThread::joltThreadReq(threadLifetimeMgmtOpCbFn callback) +void MindThread::joltThreadReq(Callback 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 callback) { std::shared_ptr caller = getSelf(); auto request = std::make_shared( @@ -253,7 +254,7 @@ void MindThread::startThreadReq(threadLifetimeMgmtOpCbFn callback) request.get(), request)); } -void MindThread::exitThreadReq(threadLifetimeMgmtOpCbFn callback) +void MindThread::exitThreadReq(Callback callback) { std::shared_ptr caller = getSelf(); auto request = std::make_shared( @@ -270,7 +271,7 @@ void MindThread::exitThreadReq(threadLifetimeMgmtOpCbFn callback) request.get(), request)); } -void MindThread::pauseThreadReq(threadLifetimeMgmtOpCbFn callback) +void MindThread::pauseThreadReq(Callback 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 callback) { if (id == ComponentThread::MRNTT) { diff --git a/smocore/deviceManager/deviceManager.cpp b/smocore/deviceManager/deviceManager.cpp index 5afe19a..e549c59 100644 --- a/smocore/deviceManager/deviceManager.cpp +++ b/smocore/deviceManager/deviceManager.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,7 @@ public: NewDeviceAttachmentSpecInd( std::shared_ptr s, const std::shared_ptr &caller, - newDeviceAttachmentSpecIndCbFn cb) + Callback cb) : PostedAsynchronousContinuation( 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 spec, - newDeviceAttachmentSpecIndCbFn callback) + Callback 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; } diff --git a/smocore/include/body/body.h b/smocore/include/body/body.h index 091d125..15ef3ce 100644 --- a/smocore/include/body/body.h +++ b/smocore/include/body/body.h @@ -3,6 +3,7 @@ #include #include +#include namespace smo { @@ -19,8 +20,8 @@ public: ~Body() = default; typedef std::function bodyLifetimeMgmtOpCbFn; - void initializeReq(bodyLifetimeMgmtOpCbFn callback); - void finalizeReq(bodyLifetimeMgmtOpCbFn callback); + void initializeReq(Callback callback); + void finalizeReq(Callback callback); private: class InitializeReq; diff --git a/smocore/include/component.h b/smocore/include/component.h index 0717f0a..85ecb4e 100644 --- a/smocore/include/component.h +++ b/smocore/include/component.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace smo { @@ -44,8 +45,8 @@ public: public: typedef std::function mrnttLifetimeMgmtOpCbFn; - void initializeReq(mrnttLifetimeMgmtOpCbFn callback); - void finalizeReq(mrnttLifetimeMgmtOpCbFn callback); + void initializeReq(Callback callback); + void finalizeReq(Callback callback); private: class MrnttLifetimeMgmtOp; diff --git a/smocore/include/componentThread.h b/smocore/include/componentThread.h index 0c70e05..56e4657 100644 --- a/smocore/include/componentThread.h +++ b/smocore/include/componentThread.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace smo { @@ -137,10 +138,10 @@ public: // Thread management methods typedef std::function threadLifetimeMgmtOpCbFn; - void startThreadReq(threadLifetimeMgmtOpCbFn callback); - void exitThreadReq(threadLifetimeMgmtOpCbFn callback); - void pauseThreadReq(threadLifetimeMgmtOpCbFn callback); - void resumeThreadReq(threadLifetimeMgmtOpCbFn callback); + void startThreadReq(Callback callback); + void exitThreadReq(Callback callback); + void pauseThreadReq(Callback callback); + void resumeThreadReq(Callback 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 callback); // CPU management methods void pinToCpu(int cpuId); diff --git a/smocore/include/deviceManager/deviceManager.h b/smocore/include/deviceManager/deviceManager.h index 5512c47..1beb771 100644 --- a/smocore/include/deviceManager/deviceManager.h +++ b/smocore/include/deviceManager/deviceManager.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace smo { namespace device { @@ -41,7 +42,7 @@ public: newDeviceAttachmentSpecIndCbFn; void newDeviceAttachmentSpecInd( std::shared_ptr spec, - newDeviceAttachmentSpecIndCbFn callback); + Callback callback); private: DeviceManager() = default; diff --git a/smocore/include/mind.h b/smocore/include/mind.h index 7d24aa7..84cb2a7 100644 --- a/smocore/include/mind.h +++ b/smocore/include/mind.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -23,8 +24,8 @@ public: ~Mind(void) = default; typedef std::function mindLifetimeMgmtOpCbFn; - void initializeReq(mindLifetimeMgmtOpCbFn callback); - void finalizeReq(mindLifetimeMgmtOpCbFn callback); + void initializeReq(Callback callback); + void finalizeReq(Callback callback); // ComponentThread access methods std::shared_ptr getComponentThread( @@ -36,11 +37,14 @@ public: // Thread management methods (moved from ComponentThread) typedef std::function mindThreadLifetimeMgmtOpCbFn; - void joltAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback); - void startAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback); - void pauseAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback); - void resumeAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback); - void exitAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback); + void joltAllMindThreadsReq(Callback callback); + void startAllMindThreadsReq( + Callback callback); + void pauseAllMindThreadsReq( + Callback callback); + void resumeAllMindThreadsReq( + Callback callback); + void exitAllMindThreadsReq(Callback callback); // CPU distribution method void distributeAndPinThreadsAcrossCpus(); diff --git a/smocore/include/senseApis/senseApiManager.h b/smocore/include/senseApis/senseApiManager.h index 3b46971..a437ee9 100644 --- a/smocore/include/senseApis/senseApiManager.h +++ b/smocore/include/senseApis/senseApiManager.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace smo { namespace sense_api { @@ -54,10 +55,10 @@ public: void attachSenseDeviceReq( const std::shared_ptr& spec, - attachSenseDeviceReqCbFn cb); + Callback cb); void detachSenseDeviceReq( const std::shared_ptr& spec, - detachSenseDeviceReqCbFn cb); + Callback cb); typedef std::function attachAllSenseDevicesFromSpecsReqCbFn; @@ -65,9 +66,9 @@ public: detachAllSenseDevicesReqCbFn; void attachAllSenseDevicesFromSpecsReq( - attachAllSenseDevicesFromSpecsReqCbFn cb); + Callback cb); void detachAllSenseDevicesReq( - detachAllSenseDevicesReqCbFn cb); + Callback cb); std::string stringifyLibs() const; diff --git a/smocore/marionette/lifetime.cpp b/smocore/marionette/lifetime.cpp index faac941..471f91e 100644 --- a/smocore/marionette/lifetime.cpp +++ b/smocore/marionette/lifetime.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -15,7 +16,7 @@ class MarionetteComponent::MrnttLifetimeMgmtOp public: MrnttLifetimeMgmtOp( MarionetteComponent &parent, const std::shared_ptr &caller, - mrnttLifetimeMgmtOpCbFn callback) + Callback callback) : PostedAsynchronousContinuation( caller, callback), parent(parent) @@ -37,10 +38,9 @@ public: } smo::mind::globalMind = std::make_shared(); - 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 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 callback) { auto mrntt = ComponentThread::getSelf(); diff --git a/smocore/marionette/main.cpp b/smocore/marionette/main.cpp index be78c28..6d382b3 100644 --- a/smocore/marionette/main.cpp +++ b/smocore/marionette/main.cpp @@ -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)}); } } diff --git a/smocore/mind.cpp b/smocore/mind.cpp index 118d5eb..082225e 100644 --- a/smocore/mind.cpp +++ b/smocore/mind.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -89,7 +90,7 @@ class Mind::MindLifetimeMgmtOp public: MindLifetimeMgmtOp( Mind &parent, const std::shared_ptr &caller, - mindLifetimeMgmtOpCbFn callback) + Callback callback) : PostedAsynchronousContinuation( 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 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 callback) { const auto& caller = ComponentThread::getSelf(); auto request = std::make_shared( @@ -258,7 +259,7 @@ class Mind::MindThreadLifetimeMgmtOp public: MindThreadLifetimeMgmtOp( Mind &parent,unsigned int nThreads, - mindThreadLifetimeMgmtOpCbFn callback) + Callback callback) : NonPostedAsynchronousContinuation(callback), loop(nThreads), parent(parent) @@ -311,21 +312,23 @@ public: } }; -void Mind::joltAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback) +void Mind::joltAllMindThreadsReq( + Callback 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 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 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 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 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)}); } } diff --git a/smocore/senseApis/senseApiManager.cpp b/smocore/senseApis/senseApiManager.cpp index 52893d5..e31e887 100644 --- a/smocore/senseApis/senseApiManager.cpp +++ b/smocore/senseApis/senseApiManager.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -268,7 +269,7 @@ public: AttachSenseDeviceReq( const std::shared_ptr& spec, const std::shared_ptr &caller, - attachSenseDeviceReqCbFn cb) + Callback cb) : PostedAsynchronousContinuation( 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& spec, - attachSenseDeviceReqCbFn cb + Callback cb ) { const auto& caller = ComponentThread::getSelf(); @@ -422,7 +423,7 @@ void SenseApiManager::attachSenseDeviceReq( void SenseApiManager::detachSenseDeviceReq( const std::shared_ptr& spec, - detachSenseDeviceReqCbFn cb + Callback cb ) { const auto& caller = ComponentThread::getSelf(); @@ -443,7 +444,7 @@ public: AttachAllSenseDevicesFromSpecsReq( const unsigned int totalNSpecs, const std::shared_ptr& caller, - attachAllSenseDevicesFromSpecsReqCbFn cb) + Callback cb) : PostedAsynchronousContinuation( 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 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 cb ) { if (device::DeviceManager::getInstance().deviceAttachmentSpecs.size() == 0) { AsynchronousLoop tmp(0); - cb(tmp); + cb.callbackFn(tmp); return; }