SenseApiDesc,xcbWindow: port to sscl coro framework

SenseApiDesc's exported API now uses coro pointers instead of
CPS fn pointers.
* Do not build this version of SMO with the Livox drivers enabled,
  because SMO has been changed at the smocore level to use coros
  when calling into stimbuffAPI libs. But the Livox drivers
  haven't yet been ported from CPS to coros.

xcbWindow has been ported to expose coros to SMO in its
senseApiDesc exported iface.
This commit is contained in:
2026-05-25 08:21:46 -04:00
parent b5fa20a2b8
commit 3e19d39853
10 changed files with 173 additions and 280 deletions
+1
View File
@@ -30,6 +30,7 @@
/* Common Libraries */ /* Common Libraries */
#cmakedefine CONFIG_LIB_XCBXORG_ENABLED #cmakedefine CONFIG_LIB_XCBXORG_ENABLED
#cmakedefine CONFIG_LIB_LIVOXPROTO1_ENABLED
#cmakedefine CONFIG_LIB_ALSA_ENABLED #cmakedefine CONFIG_LIB_ALSA_ENABLED
/* Stim Buff APIs */ /* Stim Buff APIs */
+20 -21
View File
@@ -9,7 +9,7 @@
#include <vector> #include <vector>
#include <preprocessor.h> #include <preprocessor.h>
#include <user/deviceAttachmentSpec.h> #include <user/deviceAttachmentSpec.h>
#include <spinscale/cps/callback.h> #include <spinscale/co/invokers.h>
#include <spinscale/componentThread.h> #include <spinscale/componentThread.h>
#define CL_TARGET_OPENCL_VERSION 120 #define CL_TARGET_OPENCL_VERSION 120
#include <CL/cl.h> #include <CL/cl.h>
@@ -42,25 +42,24 @@ struct SmoThreadingModelDesc
* *
* State management that's tied to a particular attachment spec should be * State management that's tied to a particular attachment spec should be
* done on the ComponentThread for the thread that SMO provided in the * done on the ComponentThread for the thread that SMO provided in the
* attachDeviceReq call. * attachDeviceCReq call.
*/ */
std::shared_ptr<sscl::ComponentThread> componentThread; std::shared_ptr<sscl::ComponentThread> componentThread;
}; };
typedef std::function<void(bool, std::shared_ptr<device::DeviceAttachmentSpec>)> struct StimBuffDeviceOpResult
sal_mlo_attachDeviceReqCbFn; {
typedef std::function<void(bool, std::shared_ptr<device::DeviceAttachmentSpec>)> bool success = false;
sal_mlo_detachDeviceReqCbFn; std::shared_ptr<device::DeviceAttachmentSpec> deviceSpec;
};
typedef int (sal_mlo_initializeIndFn)(void); using sal_mlo_initializeCIndFn = sscl::co::ViralNonPostingInvoker<int>(void);
typedef int (sal_mlo_finalizeIndFn)(void); using sal_mlo_finalizeCIndFn = sscl::co::ViralNonPostingInvoker<int>(void);
typedef void (sal_mlo_attachDeviceReqFn)( using sal_mlo_attachDeviceCReqFn = sscl::co::ViralNonPostingInvoker<StimBuffDeviceOpResult>(
const std::shared_ptr<device::DeviceAttachmentSpec>& desc, const std::shared_ptr<device::DeviceAttachmentSpec>& desc,
const std::shared_ptr<sscl::ComponentThread>& componentThread, const std::shared_ptr<sscl::ComponentThread>& componentThread);
sscl::cps::Callback<sal_mlo_attachDeviceReqCbFn> cb); using sal_mlo_detachDeviceCReqFn = sscl::co::ViralNonPostingInvoker<StimBuffDeviceOpResult>(
typedef void (sal_mlo_detachDeviceReqFn)( const std::shared_ptr<device::DeviceAttachmentSpec>& desc);
const std::shared_ptr<device::DeviceAttachmentSpec>& desc,
sscl::cps::Callback<sal_mlo_detachDeviceReqCbFn> cb);
/** /**
* @brief Hooks provided by Salmanoff to senseApi libraries. * @brief Hooks provided by Salmanoff to senseApi libraries.
@@ -138,22 +137,22 @@ struct Sal_Mgmt_LibOps
/* When Salmanoff loads a stim buff API lib, it calls this function to initialize /* When Salmanoff loads a stim buff API lib, it calls this function to initialize
* the lib. When this returns, the lib should be ready to attach devices. * the lib. When this returns, the lib should be ready to attach devices.
*/ */
sal_mlo_initializeIndFn *initializeInd; sal_mlo_initializeCIndFn *initializeCInd;
/* Salmanoff calls this to finalize the lib and free its internal /* Salmanoff calls this to finalize the lib and free its internal
* resources. When this returns, the lib should be ready to be unloaded. * resources. When this returns, the lib should be ready to be unloaded.
*/ */
sal_mlo_finalizeIndFn *finalizeInd; sal_mlo_finalizeCIndFn *finalizeCInd;
/* Salmanoff calls this to attach a device to the lib. When it returns, the /* Salmanoff calls this to attach a device to the lib. When it returns, the
* device should be attached and ready to present its stimbuff. * device should be attached and ready to present its stimbuff.
*/ */
sal_mlo_attachDeviceReqFn *attachDeviceReq; sal_mlo_attachDeviceCReqFn *attachDeviceCReq;
// When this returns, the device should be detached. // When this returns, the device should be detached.
sal_mlo_detachDeviceReqFn *detachDeviceReq; sal_mlo_detachDeviceCReqFn *detachDeviceCReq;
static bool sanityCheck(const Sal_Mgmt_LibOps &ops) static bool sanityCheck(const Sal_Mgmt_LibOps &ops)
{ {
if (!ops.initializeInd || !ops.finalizeInd if (!ops.initializeCInd || !ops.finalizeCInd
|| !ops.attachDeviceReq || !ops.detachDeviceReq) || !ops.attachDeviceCReq || !ops.detachDeviceCReq)
{ {
return false; return false;
} }
+4 -3
View File
@@ -55,8 +55,8 @@ BodyViralPostingInvoker<bool> Body::initializeCReq()
std::cout << __func__ << ": About to initializeAllStimBuffApiLibs" std::cout << __func__ << ": About to initializeAllStimBuffApiLibs"
<< '\n'; << '\n';
} }
stim_buff::StimBuffApiManager::getInstance() co_await stim_buff::StimBuffApiManager::getInstance()
.initializeAllStimBuffApiLibs(); .initializeAllStimBuffApiLibsCReq();
if (OptionParser::getOptions().verbose) if (OptionParser::getOptions().verbose)
{ {
@@ -100,7 +100,8 @@ BodyViralPostingInvoker<bool> Body::finalizeCReq()
<< " sense devices." << "\n"; << " sense devices." << "\n";
std::cout << "Mrntt: About to finalize all stim buff api libs." << "\n"; std::cout << "Mrntt: About to finalize all stim buff api libs." << "\n";
stim_buff::StimBuffApiManager::getInstance().finalizeAllStimBuffApiLibs(); co_await stim_buff::StimBuffApiManager::getInstance()
.finalizeAllStimBuffApiLibsCReq();
std::cout << "Mrntt: About to unload all stim buff api libs." << "\n"; std::cout << "Mrntt: About to unload all stim buff api libs." << "\n";
stim_buff::StimBuffApiManager::getInstance().unloadAllStimBuffApiLibs(); stim_buff::StimBuffApiManager::getInstance().unloadAllStimBuffApiLibs();
+19 -31
View File
@@ -8,7 +8,6 @@
#include <memory> #include <memory>
#include <opts.h> #include <opts.h>
#include <componentThread.h> #include <componentThread.h>
#include <cpsBoundary/stimBuffDeviceAReq.h>
#include <deviceManager/deviceManager.h> #include <deviceManager/deviceManager.h>
#include <deviceManager/deviceReattacher.h> #include <deviceManager/deviceReattacher.h>
#include <stimBuffApis/stimBuffApiManager.h> #include <stimBuffApis/stimBuffApiManager.h>
@@ -33,11 +32,6 @@ void assertMarionetteThread()
} }
} }
boost::asio::io_service &marionetteIoService()
{
return mrntt::MrnttThreadTag::io_service();
}
} // namespace } // namespace
DeviceManager::~DeviceManager() DeviceManager::~DeviceManager()
@@ -55,7 +49,7 @@ const std::string DeviceManager::stringifyDeviceSpecs(void)
return oss.str(); return oss.str();
} }
mrntt::MrnttViralPostingInvoker<cpsBoundary::StimBuffDeviceOpResult> mrntt::MrnttViralPostingInvoker<stim_buff::StimBuffDeviceOpResult>
DeviceManager::attachStimBuffDeviceCReq( DeviceManager::attachStimBuffDeviceCReq(
const std::shared_ptr<DeviceAttachmentSpec>& spec) const std::shared_ptr<DeviceAttachmentSpec>& spec)
{ {
@@ -67,7 +61,7 @@ DeviceManager::attachStimBuffDeviceCReq(
{ {
std::cerr << "attachStimBuffDeviceCReq: No library found for API '" std::cerr << "attachStimBuffDeviceCReq: No library found for API '"
<< spec->stimBuffApi << "'" << std::endl; << spec->stimBuffApi << "'" << std::endl;
co_return cpsBoundary::StimBuffDeviceOpResult{false, spec}; co_return stim_buff::StimBuffDeviceOpResult{false, spec};
} }
auto &lib = *libOpt.value(); auto &lib = *libOpt.value();
@@ -76,15 +70,15 @@ DeviceManager::attachStimBuffDeviceCReq(
{ {
std::cerr << std::string(__func__) + ": Library is being destroyed" std::cerr << std::string(__func__) + ": Library is being destroyed"
<< " for API '" << spec->stimBuffApi << "'. Bailing out.\n"; << " for API '" << spec->stimBuffApi << "'. Bailing out.\n";
co_return cpsBoundary::StimBuffDeviceOpResult{false, spec}; co_return stim_buff::StimBuffDeviceOpResult{false, spec};
} }
if (!lib.stimBuffApiDesc.sal_mgmt_libOps.attachDeviceReq) if (!lib.stimBuffApiDesc.sal_mgmt_libOps.attachDeviceCReq)
{ {
std::cerr << std::string(__func__) + ": attachDeviceReq() is NULL " std::cerr << std::string(__func__) + ": attachDeviceCReq() is NULL "
"for library '" << lib.libraryPath << "'" "for library '" << lib.libraryPath << "'"
<< std::endl; << std::endl;
co_return cpsBoundary::StimBuffDeviceOpResult{false, spec}; co_return stim_buff::StimBuffDeviceOpResult{false, spec};
} }
sscl::co::CoQutex::ReleaseHandle sbamGuard = sscl::co::CoQutex::ReleaseHandle sbamGuard =
@@ -114,14 +108,11 @@ DeviceManager::attachStimBuffDeviceCReq(
<< spec->deviceIdentifier << " to body thread" << "\n"; << spec->deviceIdentifier << " to body thread" << "\n";
} }
cpsBoundary::StimBuffDeviceOpResult result = co_await co_return co_await lib.stimBuffApiDesc.sal_mgmt_libOps.attachDeviceCReq(
cpsBoundary::AttachStimBuffDeviceAReq( spec, threadForAttachment);
spec, lib, threadForAttachment, marionetteIoService());
co_return result;
} }
mrntt::MrnttViralPostingInvoker<cpsBoundary::StimBuffDeviceOpResult> mrntt::MrnttViralPostingInvoker<stim_buff::StimBuffDeviceOpResult>
DeviceManager::detachStimBuffDeviceCReq( DeviceManager::detachStimBuffDeviceCReq(
const std::shared_ptr<DeviceAttachmentSpec>& spec) const std::shared_ptr<DeviceAttachmentSpec>& spec)
{ {
@@ -133,7 +124,7 @@ DeviceManager::detachStimBuffDeviceCReq(
{ {
std::cerr << "detachStimBuffDeviceCReq: No library found for API '" std::cerr << "detachStimBuffDeviceCReq: No library found for API '"
<< spec->stimBuffApi << "'" << std::endl; << spec->stimBuffApi << "'" << std::endl;
co_return cpsBoundary::StimBuffDeviceOpResult{false, spec}; co_return stim_buff::StimBuffDeviceOpResult{false, spec};
} }
auto &lib = *libOpt.value(); auto &lib = *libOpt.value();
@@ -142,15 +133,15 @@ DeviceManager::detachStimBuffDeviceCReq(
{ {
std::cerr << std::string(__func__) + ": Library is being destroyed" std::cerr << std::string(__func__) + ": Library is being destroyed"
<< " for API '" << spec->stimBuffApi << "'. Bailing out.\n"; << " for API '" << spec->stimBuffApi << "'. Bailing out.\n";
co_return cpsBoundary::StimBuffDeviceOpResult{false, spec}; co_return stim_buff::StimBuffDeviceOpResult{false, spec};
} }
if (!lib.stimBuffApiDesc.sal_mgmt_libOps.detachDeviceReq) if (!lib.stimBuffApiDesc.sal_mgmt_libOps.detachDeviceCReq)
{ {
std::cerr << std::string(__func__) + ": detachDeviceReq() is NULL " std::cerr << std::string(__func__) + ": detachDeviceCReq() is NULL "
"for library '" << lib.libraryPath << "'" "for library '" << lib.libraryPath << "'"
<< std::endl; << std::endl;
co_return cpsBoundary::StimBuffDeviceOpResult{false, spec}; co_return stim_buff::StimBuffDeviceOpResult{false, spec};
} }
sscl::co::CoQutex::ReleaseHandle sbamGuard = sscl::co::CoQutex::ReleaseHandle sbamGuard =
@@ -159,11 +150,8 @@ DeviceManager::detachStimBuffDeviceCReq(
co_await lib.s.lock.getAcquireInvocationAndSuspensionPolicy(); co_await lib.s.lock.getAcquireInvocationAndSuspensionPolicy();
sbamGuard.release(); sbamGuard.release();
cpsBoundary::StimBuffDeviceOpResult result = co_await co_return co_await lib.stimBuffApiDesc.sal_mgmt_libOps.detachDeviceCReq(
cpsBoundary::DetachStimBuffDeviceAReq( spec);
spec, lib, marionetteIoService());
co_return result;
} }
mrntt::MrnttViralPostingInvoker<DeviceManager::DeviceAttachmentIndResult> mrntt::MrnttViralPostingInvoker<DeviceManager::DeviceAttachmentIndResult>
@@ -243,7 +231,7 @@ DeviceManager::newDeviceAttachmentSpecIndCReq(
true, existingDeviceRole, specPtr}; true, existingDeviceRole, specPtr};
} }
cpsBoundary::StimBuffDeviceOpResult attachResult = stim_buff::StimBuffDeviceOpResult attachResult =
co_await attachStimBuffDeviceCReq(specPtr); co_await attachStimBuffDeviceCReq(specPtr);
if (!attachResult.success) if (!attachResult.success)
@@ -295,7 +283,7 @@ DeviceManager::removeDeviceAttachmentSpecCReq(
} }
// Call detachStimBuffDeviceCReq first - only clean up metadata if this succeeds // Call detachStimBuffDeviceCReq first - only clean up metadata if this succeeds
cpsBoundary::StimBuffDeviceOpResult detachResult = stim_buff::StimBuffDeviceOpResult detachResult =
co_await detachStimBuffDeviceCReq(specPtr); co_await detachStimBuffDeviceCReq(specPtr);
if (!detachResult.success) if (!detachResult.success)
@@ -473,7 +461,7 @@ DeviceManager::detachAllAttachedDeviceRolesCReq()
sscl::co::Group group; sscl::co::Group group;
std::vector< std::vector<
mrntt::MrnttViralPostingInvoker<cpsBoundary::StimBuffDeviceOpResult>> mrntt::MrnttViralPostingInvoker<stim_buff::StimBuffDeviceOpResult>>
invokers; invokers;
invokers.reserve(specsToDetach.size()); invokers.reserve(specsToDetach.size());
@@ -1,160 +0,0 @@
#ifndef STIM_BUFF_DEVICE_AREQ_H
#define STIM_BUFF_DEVICE_AREQ_H
#include <atomic>
#include <coroutine>
#include <memory>
#include <boost/asio/io_service.hpp>
#include <boost/asio/post.hpp>
#include <spinscale/cps/callback.h>
#include <stimBuffApis/stimBuffApiLib.h>
#include <user/deviceAttachmentSpec.h>
#include <user/senseApiDesc.h>
namespace smo {
namespace cpsBoundary {
struct StimBuffDeviceOpResult
{
bool success = false;
std::shared_ptr<device::DeviceAttachmentSpec> deviceSpec;
};
struct AttachStimBuffDeviceAReq
{
struct AsyncState
{
std::atomic<bool> settled{false};
StimBuffDeviceOpResult result;
std::coroutine_handle<> callerSchedHandle;
};
AttachStimBuffDeviceAReq(
const std::shared_ptr<device::DeviceAttachmentSpec> &spec,
stim_buff::StimBuffApiLib &lib,
const std::shared_ptr<sscl::ComponentThread> &threadForAttachment,
boost::asio::io_service &resumeIoService)
: asyncState(std::make_shared<AsyncState>()),
resumeIoService(resumeIoService)
{
lib.stimBuffApiDesc.sal_mgmt_libOps.attachDeviceReq(
spec, threadForAttachment,
{nullptr,
[asyncState = asyncState, &resumeIoService = resumeIoService](
bool success,
std::shared_ptr<device::DeviceAttachmentSpec> deviceSpec)
{
asyncState->result = StimBuffDeviceOpResult{
success, deviceSpec};
asyncState->settled.store(
true, std::memory_order_release);
std::coroutine_handle<> handle =
asyncState->callerSchedHandle;
if (!handle) {
return;
}
boost::asio::post(
resumeIoService,
[handle]() { handle.resume(); });
}});
}
bool await_ready() const noexcept
{
return asyncState->settled.load(std::memory_order_acquire);
}
bool await_suspend(std::coroutine_handle<> callerSchedHandle) noexcept
{
if (asyncState->settled.load(std::memory_order_acquire)) {
return false;
}
asyncState->callerSchedHandle = callerSchedHandle;
return true;
}
StimBuffDeviceOpResult await_resume() noexcept
{
return asyncState->result;
}
std::shared_ptr<AsyncState> asyncState;
boost::asio::io_service &resumeIoService;
};
struct DetachStimBuffDeviceAReq
{
struct AsyncState
{
std::atomic<bool> settled{false};
StimBuffDeviceOpResult result;
std::coroutine_handle<> callerSchedHandle;
};
DetachStimBuffDeviceAReq(
const std::shared_ptr<device::DeviceAttachmentSpec> &spec,
stim_buff::StimBuffApiLib &lib,
boost::asio::io_service &resumeIoService)
: asyncState(std::make_shared<AsyncState>()),
resumeIoService(resumeIoService)
{
lib.stimBuffApiDesc.sal_mgmt_libOps.detachDeviceReq(
spec,
{nullptr,
[asyncState = asyncState, &resumeIoService = resumeIoService](
bool success,
std::shared_ptr<device::DeviceAttachmentSpec> deviceSpec)
{
asyncState->result = StimBuffDeviceOpResult{
success, deviceSpec};
asyncState->settled.store(
true, std::memory_order_release);
std::coroutine_handle<> handle =
asyncState->callerSchedHandle;
if (!handle) {
return;
}
boost::asio::post(
resumeIoService,
[handle]() { handle.resume(); });
}});
}
bool await_ready() const noexcept
{
return asyncState->settled.load(std::memory_order_acquire);
}
bool await_suspend(std::coroutine_handle<> callerSchedHandle) noexcept
{
if (asyncState->settled.load(std::memory_order_acquire)) {
return false;
}
asyncState->callerSchedHandle = callerSchedHandle;
return true;
}
StimBuffDeviceOpResult await_resume() noexcept
{
return asyncState->result;
}
std::shared_ptr<AsyncState> asyncState;
boost::asio::io_service &resumeIoService;
};
} // namespace cpsBoundary
} // namespace smo
#endif // STIM_BUFF_DEVICE_AREQ_H
@@ -12,7 +12,6 @@
#include <deviceManager/device.h> #include <deviceManager/device.h>
#include <deviceManager/deviceRole.h> #include <deviceManager/deviceRole.h>
#include <deviceManager/deviceReattacher.h> #include <deviceManager/deviceReattacher.h>
#include <cpsBoundary/stimBuffDeviceAReq.h>
#include <marionette/marionetteThread.h> #include <marionette/marionetteThread.h>
#include <spinscale/co/coQutex.h> #include <spinscale/co/coQutex.h>
#include <spinscale/multiOperationResultSet.h> #include <spinscale/multiOperationResultSet.h>
@@ -59,11 +58,11 @@ public:
mrntt::MrnttViralPostingInvoker<DeviceAttachmentIndResult> mrntt::MrnttViralPostingInvoker<DeviceAttachmentIndResult>
removeDeviceAttachmentSpecCReq(const DeviceAttachmentSpec &spec); removeDeviceAttachmentSpecCReq(const DeviceAttachmentSpec &spec);
mrntt::MrnttViralPostingInvoker<cpsBoundary::StimBuffDeviceOpResult> mrntt::MrnttViralPostingInvoker<stim_buff::StimBuffDeviceOpResult>
attachStimBuffDeviceCReq( attachStimBuffDeviceCReq(
const std::shared_ptr<DeviceAttachmentSpec>& spec); const std::shared_ptr<DeviceAttachmentSpec>& spec);
mrntt::MrnttViralPostingInvoker<cpsBoundary::StimBuffDeviceOpResult> mrntt::MrnttViralPostingInvoker<stim_buff::StimBuffDeviceOpResult>
detachStimBuffDeviceCReq( detachStimBuffDeviceCReq(
const std::shared_ptr<DeviceAttachmentSpec>& spec); const std::shared_ptr<DeviceAttachmentSpec>& spec);
@@ -9,6 +9,7 @@
#include <functional> #include <functional>
#include <stimBuffApis/stimBuffApiLib.h> #include <stimBuffApis/stimBuffApiLib.h>
#include <user/deviceAttachmentSpec.h> #include <user/deviceAttachmentSpec.h>
#include <body/bodyThread.h>
#include <spinscale/co/coQutex.h> #include <spinscale/co/coQutex.h>
#include <spinscale/sharedResourceGroup.h> #include <spinscale/sharedResourceGroup.h>
@@ -44,15 +45,18 @@ public:
const std::string& apiName); const std::string& apiName);
void unloadStimBuffApiLib(const std::string& libraryPath); void unloadStimBuffApiLib(const std::string& libraryPath);
void initializeStimBuffApiLib(StimBuffApiLib& lib);
void finalizeStimBuffApiLib(StimBuffApiLib& lib);
void loadAllStimBuffApiLibsFromOptions( void loadAllStimBuffApiLibsFromOptions(
const std::shared_ptr<sscl::ComponentThread>& componentThread); const std::shared_ptr<sscl::ComponentThread>& componentThread);
void unloadAllStimBuffApiLibs(void); void unloadAllStimBuffApiLibs(void);
void initializeAllStimBuffApiLibs(void);
void finalizeAllStimBuffApiLibs(void); body::BodyViralPostingInvoker<void> initializeStimBuffApiLibCReq(
StimBuffApiLib &lib, bool acquireSbamLock);
body::BodyViralPostingInvoker<void> finalizeStimBuffApiLibCReq(
StimBuffApiLib &lib, bool acquireSbamLock);
body::BodyViralPostingInvoker<void> initializeAllStimBuffApiLibsCReq();
body::BodyViralPostingInvoker<void> finalizeAllStimBuffApiLibsCReq();
std::string stringifyLibs() const; std::string stringifyLibs() const;
+97 -33
View File
@@ -4,6 +4,8 @@
#include <filesystem> #include <filesystem>
#include <stimBuffApis/stimBuffApiManager.h> #include <stimBuffApis/stimBuffApiManager.h>
#include <stimBuffApis/stimBuffApiLib.h> #include <stimBuffApis/stimBuffApiLib.h>
#include <body/bodyThread.h>
#include <componentThread.h>
#include <opts.h> #include <opts.h>
#include <user/senseApiDesc.h> #include <user/senseApiDesc.h>
#include <mind.h> #include <mind.h>
@@ -17,6 +19,21 @@ namespace fs = std::filesystem;
namespace smo { namespace smo {
namespace stim_buff { namespace stim_buff {
namespace {
void assertBodyThread()
{
auto self = sscl::ComponentThread::getSelf();
if (self->id != SmoThreadId::BODY)
{
throw std::runtime_error(
std::string(__func__)
+ ": Must be executed on Body thread");
}
}
} // namespace
/** /**
* @brief Searches for a library in predefined locations * @brief Searches for a library in predefined locations
* @param libraryPath The name or path of the library to find * @param libraryPath The name or path of the library to find
@@ -269,49 +286,96 @@ std::string StimBuffApiManager::stringifyLibs() const
return result; return result;
} }
void StimBuffApiManager::initializeStimBuffApiLib(StimBuffApiLib& lib) body::BodyViralPostingInvoker<void>
StimBuffApiManager::initializeStimBuffApiLibCReq(
StimBuffApiLib &lib, bool acquireSbamLock)
{ {
/** FIXME: assertBodyThread();
* When we eventually make this method async, this method should acquire
* the StimBuffApiManager's main CRUD qutex. StimBuffApiManager &sbam = getInstance();
*/ std::optional<sscl::co::CoQutex::ReleaseHandle> sbamGuard;
if (!lib.stimBuffApiDesc.sal_mgmt_libOps.initializeInd) if (acquireSbamLock)
{ {
throw std::runtime_error( sbamGuard.emplace(
std::string(__func__) + ": initializeInd() is NULL for library '" co_await sbam.s.lock.getAcquireInvocationAndSuspensionPolicy());
+ lib.libraryPath + "'"); }
}
lib.stimBuffApiDesc.sal_mgmt_libOps.initializeInd(); if (!lib.stimBuffApiDesc.sal_mgmt_libOps.initializeCInd)
{
throw std::runtime_error(
std::string(__func__) + ": initializeCInd() is NULL for library '"
+ lib.libraryPath + "'");
}
sscl::co::CoQutex::ReleaseHandle libGuard =
co_await lib.s.lock.getAcquireInvocationAndSuspensionPolicy();
co_await lib.stimBuffApiDesc.sal_mgmt_libOps.initializeCInd();
co_return;
} }
void StimBuffApiManager::finalizeStimBuffApiLib(StimBuffApiLib& lib) body::BodyViralPostingInvoker<void>
StimBuffApiManager::finalizeStimBuffApiLibCReq(
StimBuffApiLib &lib, bool acquireSbamLock)
{ {
/** FIXME: assertBodyThread();
* When we eventually make this method async, this flag should only be set
* after acquiring the StimBuffApiManager's main CRUD qutex. StimBuffApiManager &sbam = getInstance();
*/ std::optional<sscl::co::CoQutex::ReleaseHandle> sbamGuard;
lib.isBeingDestroyed.store(true); if (acquireSbamLock)
if (!lib.stimBuffApiDesc.sal_mgmt_libOps.finalizeInd) {
{ sbamGuard.emplace(
throw std::runtime_error( co_await sbam.s.lock.getAcquireInvocationAndSuspensionPolicy());
std::string(__func__) + ": finalizeInd() is NULL for library '" }
+ lib.libraryPath + "'");
} lib.isBeingDestroyed.store(true);
lib.stimBuffApiDesc.sal_mgmt_libOps.finalizeInd();
if (!lib.stimBuffApiDesc.sal_mgmt_libOps.finalizeCInd)
{
throw std::runtime_error(
std::string(__func__) + ": finalizeCInd() is NULL for library '"
+ lib.libraryPath + "'");
}
sscl::co::CoQutex::ReleaseHandle libGuard =
co_await lib.s.lock.getAcquireInvocationAndSuspensionPolicy();
co_await lib.stimBuffApiDesc.sal_mgmt_libOps.finalizeCInd();
co_return;
} }
void StimBuffApiManager::initializeAllStimBuffApiLibs(void) body::BodyViralPostingInvoker<void>
StimBuffApiManager::initializeAllStimBuffApiLibsCReq()
{ {
for (auto& lib : getInstance().s.rsrc.stimBuffApiLibs) { assertBodyThread();
initializeStimBuffApiLib(*lib);
} StimBuffApiManager &sbam = getInstance();
sscl::co::CoQutex::ReleaseHandle sbamGuard =
co_await sbam.s.lock.getAcquireInvocationAndSuspensionPolicy();
for (auto &lib : sbam.s.rsrc.stimBuffApiLibs) {
co_await initializeStimBuffApiLibCReq(*lib, false);
}
co_return;
} }
void StimBuffApiManager::finalizeAllStimBuffApiLibs(void) body::BodyViralPostingInvoker<void>
StimBuffApiManager::finalizeAllStimBuffApiLibsCReq()
{ {
for (auto& lib : getInstance().s.rsrc.stimBuffApiLibs) { assertBodyThread();
finalizeStimBuffApiLib(*lib);
} StimBuffApiManager &sbam = getInstance();
sscl::co::CoQutex::ReleaseHandle sbamGuard =
co_await sbam.s.lock.getAcquireInvocationAndSuspensionPolicy();
for (auto &lib : sbam.s.rsrc.stimBuffApiLibs) {
co_await finalizeStimBuffApiLibCReq(*lib, false);
}
co_return;
} }
+2 -1
View File
@@ -28,7 +28,8 @@ if(ENABLE_STIMBUFFAPI_xcbWindow)
target_link_libraries(xcbWindow target_link_libraries(xcbWindow
Boost::system Boost::log Boost::system Boost::log
${XCB_LIBRARIES} ${XCB_LIBRARIES}
attachmentSupport) attachmentSupport
spinscale)
# Install rules # Install rules
install(TARGETS xcbWindow install(TARGETS xcbWindow
+19 -23
View File
@@ -8,7 +8,7 @@
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <user/senseApiDesc.h> #include <user/senseApiDesc.h>
#include <user/deviceAttachmentSpec.h> #include <user/deviceAttachmentSpec.h>
#include <spinscale/cps/callback.h> #include <spinscale/co/invokers.h>
#include <xcbXorg/xcbXorg.h> #include <xcbXorg/xcbXorg.h>
#include "xcbWindow.h" #include "xcbWindow.h"
@@ -214,7 +214,7 @@ AttachedWindow::~AttachedWindow()
} // namespace xcb_window } // namespace xcb_window
// SenseApi functions // SenseApi functions
static int xcbWindow_initializeInd(void) static sscl::co::ViralNonPostingInvoker<int> xcbWindow_initializeCInd(void)
{ {
if (!smoHooksPtr) if (!smoHooksPtr)
{ {
@@ -257,10 +257,10 @@ static int xcbWindow_initializeInd(void)
": Failed to get required function pointers from libxcbXorg"); ": Failed to get required function pointers from libxcbXorg");
} }
return 0; co_return 0;
} }
static int xcbWindow_finalizeInd(void) static sscl::co::ViralNonPostingInvoker<int> xcbWindow_finalizeCInd(void)
{ {
g_attachedWindows.clear(); g_attachedWindows.clear();
@@ -271,14 +271,13 @@ static int xcbWindow_finalizeInd(void)
xcbXorg.fns = { nullptr, nullptr, nullptr, nullptr, nullptr }; xcbXorg.fns = { nullptr, nullptr, nullptr, nullptr, nullptr };
} }
return 0; co_return 0;
} }
static void xcbWindow_attachDeviceReq( static sscl::co::ViralNonPostingInvoker<smo::stim_buff::StimBuffDeviceOpResult>
xcbWindow_attachDeviceCReq(
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& desc, const std::shared_ptr<smo::device::DeviceAttachmentSpec>& desc,
const std::shared_ptr<sscl::ComponentThread>& componentThread, const std::shared_ptr<sscl::ComponentThread>& componentThread)
sscl::cps::Callback<smo::stim_buff::sal_mlo_attachDeviceReqCbFn> cb
)
{ {
// Not used yet, but may be used later. // Not used yet, but may be used later.
(void)componentThread; (void)componentThread;
@@ -289,21 +288,19 @@ static void xcbWindow_attachDeviceReq(
} catch (const std::exception& exc) { } catch (const std::exception& exc) {
std::cerr << __func__ << ": Exception while attaching X11 window: " std::cerr << __func__ << ": Exception while attaching X11 window: "
<< exc.what() << "\n"; << exc.what() << "\n";
cb.callbackFn(false, desc); co_return smo::stim_buff::StimBuffDeviceOpResult{false, desc};
return;
} }
std::cout << __func__ << ": Attached X11 window:\n " std::cout << __func__ << ": Attached X11 window:\n "
<< g_attachedWindows.back()->stringify() << g_attachedWindows.back()->stringify()
<< "\n"; << "\n";
cb.callbackFn(true, desc); co_return smo::stim_buff::StimBuffDeviceOpResult{true, desc};
} }
static void xcbWindow_detachDeviceReq( static sscl::co::ViralNonPostingInvoker<smo::stim_buff::StimBuffDeviceOpResult>
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec, xcbWindow_detachDeviceCReq(
sscl::cps::Callback<smo::stim_buff::sal_mlo_detachDeviceReqCbFn> cb const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec)
)
{ {
auto it = std::find_if(g_attachedWindows.begin(), g_attachedWindows.end(), auto it = std::find_if(g_attachedWindows.begin(), g_attachedWindows.end(),
[&spec](const std::unique_ptr<xcb_window::AttachedWindow>& window) { [&spec](const std::unique_ptr<xcb_window::AttachedWindow>& window) {
@@ -316,15 +313,14 @@ static void xcbWindow_detachDeviceReq(
std::cerr << __func__ << ": Device not found for detachment:\n" std::cerr << __func__ << ": Device not found for detachment:\n"
<< spec->stringify() << "\n"; << spec->stringify() << "\n";
cb.callbackFn(false, spec); co_return smo::stim_buff::StimBuffDeviceOpResult{false, spec};
return;
} }
g_attachedWindows.erase(it); g_attachedWindows.erase(it);
std::cout << __func__ << ": Detached X11 window device:\n" std::cout << __func__ << ": Detached X11 window device:\n"
<< spec->stringify() << "\n"; << spec->stringify() << "\n";
cb.callbackFn(true, spec); co_return smo::stim_buff::StimBuffDeviceOpResult{true, spec};
} }
// SenseApi descriptor // SenseApi descriptor
@@ -332,10 +328,10 @@ static smo::stim_buff::StimBuffApiDesc xcbWindowApiDesc = {
.name = "xcb", .name = "xcb",
.exportedQualeIfaceApis = { { "visual-qualeiface" } }, .exportedQualeIfaceApis = { { "visual-qualeiface" } },
.sal_mgmt_libOps = { .sal_mgmt_libOps = {
.initializeInd = xcbWindow_initializeInd, .initializeCInd = xcbWindow_initializeCInd,
.finalizeInd = xcbWindow_finalizeInd, .finalizeCInd = xcbWindow_finalizeCInd,
.attachDeviceReq = xcbWindow_attachDeviceReq, .attachDeviceCReq = xcbWindow_attachDeviceCReq,
.detachDeviceReq = xcbWindow_detachDeviceReq .detachDeviceCReq = xcbWindow_detachDeviceCReq
} }
}; };