SenseApis: Make attachDeviceReq async in drivers and SenseApiMgr

Slowly retrogressively making these sequences async
This commit is contained in:
2025-09-10 06:51:55 -04:00
parent 5b5a701c69
commit 1b6b12256d
9 changed files with 282 additions and 116 deletions
+148 -14
View File
@@ -255,11 +255,19 @@ void SenseApiManager::finalizeAllSenseApiLibs(void)
}
}
void SenseApiManager::attachSenseDevice(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec
void SenseApiManager::attachSenseDeviceReq(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec,
attachSenseDeviceReqCbFn cb
)
{
auto libOpt = getSenseApiLibByApiName(spec->api);
/** FIXME:
* We should acquire a spinlock here to ensure that the device isn't added
* in the interim while the async op executes.
*/
auto libOpt = getSenseApiLibByApiName(spec->api);
if (!libOpt)
{
throw std::runtime_error(
@@ -273,13 +281,19 @@ void SenseApiManager::attachSenseDevice(
std::string(__func__) + ": attachDeviceReq() is NULL for library '"
+ lib.libraryPath + "'");
}
lib.senseApiDesc.sal_mgmt_libOps.attachDeviceReq(spec);
lib.senseApiDesc.sal_mgmt_libOps.attachDeviceReq(spec, cb);
}
void SenseApiManager::detachSenseDevice(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec
void SenseApiManager::detachSenseDeviceReq(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec,
detachSenseDeviceReqCbFn cb
)
{
/** FIXME:
* We should acquire a spinlock here to ensure that the device isn't removed
* in the interim while the async op executes.
*/
auto libOpt = getSenseApiLibByApiName(spec->api);
if (!libOpt)
{
@@ -294,21 +308,141 @@ void SenseApiManager::detachSenseDevice(
std::string(__func__) + ": detachDeviceReq() is NULL for library '"
+ lib.libraryPath + "'");
}
lib.senseApiDesc.sal_mgmt_libOps.detachDeviceReq(spec);
lib.senseApiDesc.sal_mgmt_libOps.detachDeviceReq(spec, cb);
}
void SenseApiManager::attachAllSenseDevicesFromSpecs(void)
{
for (const auto& spec : device::DeviceManager::deviceAttachmentSpecs) {
attachSenseDevice(spec);
}
std::atomic<int> nTotal = device::DeviceManager::deviceAttachmentSpecs
.size();
std::atomic<int> nSucceeded = 0, nFailed = 0;
auto self = ComponentThread::getSelf();
for (const auto& spec : device::DeviceManager::deviceAttachmentSpecs)
{
try {
attachSenseDeviceReq(spec,
[spec, &nTotal, &nSucceeded, &nFailed, caller = self](bool success) -> void
{
if (!success)
{
++nFailed;
std::cerr << __func__ << ": Failed to attach device: "
<< spec->deviceIdentifier << "\n";
caller->getIoService().post([]{});
return;
}
++nSucceeded;
if (nSucceeded.load() + nFailed.load() != nTotal.load()) {
return;
}
std::cout << __func__ << ": " << nSucceeded.load()
<< " devices attached, "
<< nFailed.load() << " devices failed\n";
caller->getIoService().post([]{});
});
} catch (const std::exception& e) {
std::cerr << __func__ << ": Exception: " << e.what() << "\n";
++nFailed;
}
}
/* Bridge the async op here. */
for (;;)
{
self->getIoService().run_one();
if ((nSucceeded.load() + nFailed.load() == nTotal.load())
|| self->getIoService().stopped())
{
break;
}
}
if (self->getIoService().stopped())
{
/* Return early because the io_service is stopped. */
return;
}
if (nTotal.load() != nSucceeded.load() + nFailed.load())
{
throw std::runtime_error(
std::string(__func__) + ": Failed to get through all devices");
}
std::cout << __func__ << ": " << nSucceeded.load() << "/" << nTotal.load()
<< " devices attached, "
<< nFailed.load() << "/" << nTotal.load() << " devices failed\n";
}
void SenseApiManager::detachAllSenseDevices(void)
void SenseApiManager::detachAllSenseDevicesReq(void)
{
for (const auto& spec : device::DeviceManager::deviceAttachmentSpecs) {
detachSenseDevice(spec);
}
std::atomic<int> nTotal = device::DeviceManager::deviceAttachmentSpecs
.size();
std::atomic<int> nSucceeded = 0, nFailed = 0;
auto self = ComponentThread::getSelf();
for (const auto& spec : device::DeviceManager::deviceAttachmentSpecs)
{
try {
detachSenseDeviceReq(spec,
[spec, &nTotal, &nSucceeded, &nFailed, caller = self](bool success) -> void
{
if (!success)
{
++nFailed;
std::cerr << __func__ << ": Failed to detach device: "
<< spec->deviceIdentifier << "\n";
caller->getIoService().post([]{});
return;
}
++nSucceeded;
if (nSucceeded.load() + nFailed.load() != nTotal.load()) {
return;
}
std::cout << __func__ << ": " << nSucceeded.load()
<< " devices detached, "
<< nFailed.load() << " devices failed\n";
caller->getIoService().post([]{});
});
} catch (const std::exception& e) {
std::cerr << __func__ << ": Exception: " << e.what() << "\n";
++nFailed;
}
}
/* Bridge the async op here. */
for (;;)
{
self->getIoService().run_one();
if ((nSucceeded.load() + nFailed.load() == nTotal.load())
|| self->getIoService().stopped())
{
break;
}
}
if (self->getIoService().stopped())
{
/* Return early because the io_service is stopped. */
return;
}
if (nTotal.load() != nSucceeded.load() + nFailed.load())
{
throw std::runtime_error(
std::string(__func__) + ": Failed to get through all devices");
}
std::cout << __func__ << ": " << nSucceeded.load() << "/" << nTotal.load()
<< " devices detached, "
<< nFailed.load() << "/" << nTotal.load() << " devices failed\n";
}
} // namespace sense_api