Add our first async thread sequence

Gave me some ideas about how things should be structured. Apparently
merely using region-data-locked threads doesn't eliminate the need
for synchronization/locking. It just means your synchronization is much
lighter, in the form of localized variables.

It seems we'll need to maintain boolean trackers for certain
operations that shouldn't be performed concomitantly, and deny
the caller access to those operations in order to preserve
data sanity.

I guess we still ended up using locking after all. Tbh, I'm not even
sure this will make things end up being lighter: we may have to bounce
requests off, or perhaps re-enqueue them into the queue?

So maybe instead of bouncing requests off, we could re-add them to the
rear of the queue when they conflict with an ongoing request.
This commit is contained in:
2025-08-29 17:42:13 -04:00
parent bb7be7fb3c
commit d217354689
3 changed files with 121 additions and 0 deletions
+77
View File
@@ -7,6 +7,7 @@
#include <memory>
#include <opts.h>
#include <deviceManager/deviceManager.h>
#include <senseApis/senseApiManager.h>
namespace smo {
namespace device {
@@ -17,6 +18,26 @@ std::vector<std::shared_ptr<ExtrospectorDevAttachmentSpec>>
DeviceManager::extrospectorDeviceSpecs;
std::vector<std::shared_ptr<DeviceAttachmentSpec>>
DeviceManager::deviceAttachmentSpecs;
std::vector<std::shared_ptr<Device>>
DeviceManager::devices;
// Async continuation structure
struct DeviceAttachmentContinuation {
std::shared_ptr<DeviceAttachmentSpec> spec;
std::function<void(
bool success, std::shared_ptr<Device> device,
std::shared_ptr<DeviceAttachmentSpec> deviceSpec)
> callback;
DeviceAttachmentContinuation(
std::shared_ptr<DeviceAttachmentSpec> s,
std::function<void(
bool success, std::shared_ptr<Device> device,
std::shared_ptr<DeviceAttachmentSpec> deviceSpec)
> cb)
: spec(s), callback(cb)
{}
};
const std::string DeviceManager::stringifyDeviceSpecs(void)
{
@@ -33,5 +54,61 @@ const std::string DeviceManager::stringifyDeviceSpecs(void)
return oss.str();
}
void DeviceManager::newDeviceAttachmentSpecInd(
std::shared_ptr<DeviceAttachmentSpec> spec,
std::function<void(
bool success, std::shared_ptr<Device> device,
std::shared_ptr<DeviceAttachmentSpec> deviceSpec)
> callback)
{
// Create async continuation
auto continuation = std::make_shared<DeviceAttachmentContinuation>(
spec, callback);
// Check if a DeviceAttachmentSpec already matches
for (const auto& existingSpec : deviceAttachmentSpecs)
{
if (!(*existingSpec == *spec)) { continue; }
// Already exists, callback with error
callback(false, nullptr, nullptr);
return;
}
// Try to attach the sense device
try {
sense_api::SenseApiManager::getInstance().attachSenseDevice(spec);
// Look for existing Device with same identifier
std::shared_ptr<Device> device = nullptr;
for (const auto& existingDevice : devices)
{
if (existingDevice->deviceIdentifier != spec->deviceIdentifier)
{ continue; }
device = existingDevice;
break;
}
// If device doesn't exist, create a new one and add it
if (!device)
{
device = std::make_shared<Device>(spec->deviceIdentifier);
devices.push_back(device);
}
// Add DeviceAttachmentSpec to device's list
device->deviceAttachmentSpecs.push_back(spec);
// Add DeviceAttachmentSpec to DeviceManager's list
deviceAttachmentSpecs.push_back(spec);
// Callback with success
callback(true, device, spec);
} catch (const std::exception& e) {
// Attach failed, callback with error
callback(false, nullptr, nullptr);
}
}
} // namespace device
} // namespace smo
+36
View File
@@ -0,0 +1,36 @@
#ifndef DEVICE_H
#define DEVICE_H
#include <string>
#include <vector>
#include <memory>
#include <sstream>
#include <user/deviceAttachmentSpec.h>
namespace smo {
namespace device {
class Device
{
public:
std::string deviceIdentifier;
std::vector<std::shared_ptr<DeviceAttachmentSpec>> deviceAttachmentSpecs;
Device(const std::string& identifier) : deviceIdentifier(identifier) {}
std::string stringify() const
{
std::ostringstream os;
os << "Device Identifier: " << deviceIdentifier
<< ", Attachment Specs: " << deviceAttachmentSpecs.size() << std::endl;
for (const auto& spec : deviceAttachmentSpecs) {
os << " " << spec->stringify();
}
return os.str();
}
};
} // namespace device
} // namespace smo
#endif // DEVICE_H
@@ -8,6 +8,8 @@
#include <utility>
#include <iostream>
#include <user/deviceAttachmentSpec.h>
#include <deviceManager/device.h>
#include <functional>
namespace smo {
namespace device {
@@ -27,6 +29,11 @@ public:
static const std::string stringifyDeviceSpecs(void);
// New async function for device attachment
void newDeviceAttachmentSpecInd(
std::shared_ptr<DeviceAttachmentSpec> spec,
std::function<void(bool success, std::shared_ptr<Device> device, std::shared_ptr<DeviceAttachmentSpec> deviceSpec)> callback);
private:
DeviceManager() = default;
~DeviceManager() = default;
@@ -41,6 +48,7 @@ public:
extrospectorDeviceSpecs;
static std::vector<std::shared_ptr<DeviceAttachmentSpec>>
deviceAttachmentSpecs;
static std::vector<std::shared_ptr<Device>> devices;
};
} // namespace device