SenseApis: Add threading model info to initialization info

We provide access to a thread whose event queue the sense API
libs can use for device-independent event management.
This commit is contained in:
2025-09-04 17:35:49 -04:00
parent 1d9b8a2cf6
commit e5a3c41c20
7 changed files with 68 additions and 13 deletions
+27 -1
View File
@@ -6,11 +6,34 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include <preprocessor.h> #include <preprocessor.h>
#include <componentThread.h>
#include <user/deviceAttachmentSpec.h> #include <user/deviceAttachmentSpec.h>
namespace smo { namespace smo {
namespace sense_api { namespace sense_api {
/**
* @brief Threading model descriptor for senseApi libraries.
*
* This structure provides senseApi libraries with access to the information and
* resources they need to operate with SMO's threading model.
*/
struct SmoThreadingModelDesc
{
/**
* @brief Shared pointer to ComponentThread for device-independent state management.
*
* This ComponentThread should be used by senseApis for state management
* that's independent of any particular device or attachment spec.
* SMO will usually pass in the Marionette thread here.
*
* State management that's tied to a particular attachment spec should be
* done on the ComponentThread for the thread that SMO provided in the
* attachDeviceReq call.
*/
std::shared_ptr<ComponentThread> componentThread;
};
typedef int (sal_mlo_initializeIndFn)(void); typedef int (sal_mlo_initializeIndFn)(void);
typedef int (sal_mlo_finalizeIndFn)(void); typedef int (sal_mlo_finalizeIndFn)(void);
typedef int (sal_mlo_attachDeviceReqFn)( typedef int (sal_mlo_attachDeviceReqFn)(
@@ -134,9 +157,12 @@ public:
* *
* The SalmanoffCallbacks parameter provides the library with access to * The SalmanoffCallbacks parameter provides the library with access to
* Salmanoff's hooks. * Salmanoff's hooks.
* The SmoThreadingModelDesc parameter provides the library with access to
* the io_service for network operations and event handling.
*/ */
typedef const SenseApiDesc &(SMO_GET_SENSE_API_DESC_FN_TYPEDEF)( typedef const SenseApiDesc &(SMO_GET_SENSE_API_DESC_FN_TYPEDEF)(
const SalmanoffCallbacks& callbacks); const SalmanoffCallbacks& callbacks,
const SmoThreadingModelDesc& threadingModel);
} // namespace sense_api } // namespace sense_api
} // namespace smo } // namespace smo
+4 -1
View File
@@ -29,6 +29,7 @@ static XcbXorgDllState xcbXorg;
// Salmanoff hooks, obtained from SMO_GET_SENSE_API_DESC_FN_NAME(). // Salmanoff hooks, obtained from SMO_GET_SENSE_API_DESC_FN_NAME().
static const smo::sense_api::SalmanoffCallbacks* smoHooksPtr = nullptr; static const smo::sense_api::SalmanoffCallbacks* smoHooksPtr = nullptr;
static smo::sense_api::SmoThreadingModelDesc smoThreadingModelDesc;
// Attached windows. // Attached windows.
static std::vector<std::unique_ptr<xcb_window::AttachedWindow>> static std::vector<std::unique_ptr<xcb_window::AttachedWindow>>
@@ -348,8 +349,10 @@ extern "C" smo::sense_api::SMO_GET_SENSE_API_DESC_FN_TYPEDEF
SMO_GET_SENSE_API_DESC_FN_NAME; SMO_GET_SENSE_API_DESC_FN_NAME;
const smo::sense_api::SenseApiDesc& SMO_GET_SENSE_API_DESC_FN_NAME( const smo::sense_api::SenseApiDesc& SMO_GET_SENSE_API_DESC_FN_NAME(
const smo::sense_api::SalmanoffCallbacks& callbacks) const smo::sense_api::SalmanoffCallbacks& callbacks,
const smo::sense_api::SmoThreadingModelDesc& threadingModel)
{ {
smoHooksPtr = &callbacks; smoHooksPtr = &callbacks;
smoThreadingModelDesc = threadingModel;
return xcbWindowApiDesc; return xcbWindowApiDesc;
} }
+4 -1
View File
@@ -1,9 +1,12 @@
#ifndef _SALMANOFF_H #ifndef _SALMANOFF_H
#define _SALMANOFF_H #define _SALMANOFF_H
#include <memory>
#include <componentThread.h>
namespace smo { namespace smo {
void initializeSalmanoff(void); void initializeSalmanoff(std::shared_ptr<ComponentThread>& componentThread);
void shutdownSalmanoff(void); void shutdownSalmanoff(void);
} // namespace smo } // namespace smo
+8 -2
View File
@@ -7,6 +7,7 @@
#include <string> #include <string>
#include <optional> #include <optional>
#include <functional> #include <functional>
#include <componentThread.h>
#include <senseApis/senseApiLib.h> #include <senseApis/senseApiLib.h>
#include <user/deviceAttachmentSpec.h> #include <user/deviceAttachmentSpec.h>
@@ -22,7 +23,10 @@ public:
return instance; return instance;
} }
SenseApiLib& loadSenseApiLib(const std::string& libraryPath); SenseApiLib& loadSenseApiLib(
const std::string& libraryPath,
std::shared_ptr<ComponentThread>& componentThread);
std::optional<std::shared_ptr<SenseApiLib>> getSenseApiLib( std::optional<std::shared_ptr<SenseApiLib>> getSenseApiLib(
const std::string& libraryPath); const std::string& libraryPath);
std::optional<std::shared_ptr<SenseApiLib>> getSenseApiLibByApiName( std::optional<std::shared_ptr<SenseApiLib>> getSenseApiLibByApiName(
@@ -32,7 +36,9 @@ public:
void initializeSenseApiLib(SenseApiLib& lib); void initializeSenseApiLib(SenseApiLib& lib);
void finalizeSenseApiLib(SenseApiLib& lib); void finalizeSenseApiLib(SenseApiLib& lib);
void loadAllSenseApiLibsFromOptions(void); void loadAllSenseApiLibsFromOptions(
std::shared_ptr<ComponentThread>& componentThread);
void unloadAllSenseApiLibs(void); void unloadAllSenseApiLibs(void);
void initializeAllSenseApiLibs(void); void initializeAllSenseApiLibs(void);
void finalizeAllSenseApiLibs(void); void finalizeAllSenseApiLibs(void);
+1 -1
View File
@@ -75,7 +75,7 @@ void ComponentThread::marionetteMain(ComponentThread& self)
throw JustPrintUsageNoError(options); throw JustPrintUsageNoError(options);
} }
initializeSalmanoff(); initializeSalmanoff(mrntt::mrntt);
self.getIoService().post([]() self.getIoService().post([]()
{ {
// Initialize the global Mind object // Initialize the global Mind object
+2 -2
View File
@@ -4,14 +4,14 @@
namespace smo { namespace smo {
void initializeSalmanoff(void) void initializeSalmanoff(std::shared_ptr<ComponentThread>& componentThread)
{ {
std::cout << __func__ << ": Entered." << std::endl; std::cout << __func__ << ": Entered." << std::endl;
device::DeviceManager::getInstance().collateAllDapSpecs(); device::DeviceManager::getInstance().collateAllDapSpecs();
device::DeviceManager::getInstance().parseAllDapSpecs(); device::DeviceManager::getInstance().parseAllDapSpecs();
std::cout << device::DeviceManager::stringifyDeviceSpecs() << std::endl; std::cout << device::DeviceManager::stringifyDeviceSpecs() << std::endl;
sense_api::SenseApiManager::getInstance().loadAllSenseApiLibsFromOptions(); sense_api::SenseApiManager::getInstance().loadAllSenseApiLibsFromOptions(componentThread);
std::cout << sense_api::SenseApiManager::getInstance().stringifyLibs() std::cout << sense_api::SenseApiManager::getInstance().stringifyLibs()
<< std::endl; << std::endl;
std::cerr << "About to initializeAllSenseApiLibs" << std::endl; std::cerr << "About to initializeAllSenseApiLibs" << std::endl;
+21 -4
View File
@@ -74,13 +74,21 @@ static SalmanoffCallbacks salmanoffCallbacks =
.searchForLibInSmoSearchPaths = searchForLibInSmoSearchPaths .searchForLibInSmoSearchPaths = searchForLibInSmoSearchPaths
}; };
/* Static file-scope threading model object for senseApi libraries */
static SmoThreadingModelDesc smoThreadingModelDesc = {
.componentThread = nullptr
};
std::optional<std::string> SenseApiManager::searchForLibInSmoSearchPaths( std::optional<std::string> SenseApiManager::searchForLibInSmoSearchPaths(
const std::string& libraryPath) const std::string& libraryPath)
{ {
return ::smo::sense_api::searchForLibInSmoSearchPaths(libraryPath); return ::smo::sense_api::searchForLibInSmoSearchPaths(libraryPath);
} }
SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath) SenseApiLib& SenseApiManager::loadSenseApiLib(
const std::string& libraryPath,
std::shared_ptr<ComponentThread>& componentThread
)
{ {
std::optional<std::string> fullPath = searchForLibInSmoSearchPaths( std::optional<std::string> fullPath = searchForLibInSmoSearchPaths(
libraryPath); libraryPath);
@@ -121,7 +129,14 @@ SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
+ libraryPath + "'"); + libraryPath + "'");
} }
const SenseApiDesc &libApiDesc = func(salmanoffCallbacks); // Check if the static threading model obj is null and initialize if needed
if (!smoThreadingModelDesc.componentThread) {
smoThreadingModelDesc.componentThread = componentThread;
}
const SenseApiDesc &libApiDesc = func(
salmanoffCallbacks, smoThreadingModelDesc);
auto lib = std::make_shared<SenseApiLib>( auto lib = std::make_shared<SenseApiLib>(
libraryPath, dlopen_handle.release(), func); libraryPath, dlopen_handle.release(), func);
lib->setSenseApiDesc(libApiDesc); lib->setSenseApiDesc(libApiDesc);
@@ -178,11 +193,13 @@ void SenseApiManager::unloadAllSenseApiLibs(void)
senseApiLibs.clear(); senseApiLibs.clear();
} }
void SenseApiManager::loadAllSenseApiLibsFromOptions() void SenseApiManager::loadAllSenseApiLibsFromOptions(
std::shared_ptr<ComponentThread>& componentThread
)
{ {
const auto& options = OptionParser::getOptions(); const auto& options = OptionParser::getOptions();
for (const auto& libPath : options.senseApiLibs) { for (const auto& libPath : options.senseApiLibs) {
loadSenseApiLib(libPath); loadSenseApiLib(libPath, componentThread);
} }
} }