Make [at|de]tachAllSenseDevices[FromSpecs] and initializeSalmanoff async
This is the culmination of a lot of changes over the last week. We're making SMO basically fully async in many areas, and then preparing to implement the spinqueueing mechanism for locking.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <senseApis/senseApiLib.h>
|
||||
#include <opts.h>
|
||||
#include <asynchronousBridge.h>
|
||||
#include <asynchronousContinuation.h>
|
||||
#include <asynchronousLoop.h>
|
||||
#include <user/senseApiDesc.h>
|
||||
#include <deviceManager/deviceManager.h>
|
||||
@@ -257,8 +258,6 @@ void SenseApiManager::finalizeAllSenseApiLibs(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SenseApiManager::attachSenseDeviceReq(
|
||||
const std::shared_ptr<device::DeviceAttachmentSpec>& spec,
|
||||
attachSenseDeviceReqCbFn cb
|
||||
@@ -313,118 +312,130 @@ void SenseApiManager::detachSenseDeviceReq(
|
||||
lib.senseApiDesc.sal_mgmt_libOps.detachDeviceReq(spec, cb);
|
||||
}
|
||||
|
||||
void SenseApiManager::attachAllSenseDevicesFromSpecs(void)
|
||||
class SenseApiManager::AttachAllSenseDevicesFromSpecsReq
|
||||
: public AsynchronousContinuation<attachAllSenseDevicesFromSpecsReqCbFn>
|
||||
{
|
||||
auto self = ComponentThread::getSelf();
|
||||
AsynchronousBridge bridge(self->getIoService());
|
||||
AsynchronousLoop loop(device::DeviceManager::deviceAttachmentSpecs.size());
|
||||
public:
|
||||
AttachAllSenseDevicesFromSpecsReq(
|
||||
const unsigned int totalNSpecs,
|
||||
attachAllSenseDevicesFromSpecsReqCbFn cb)
|
||||
: AsynchronousContinuation(std::move(cb)),
|
||||
loop(totalNSpecs)
|
||||
{}
|
||||
|
||||
// Callback methods for the attachment sequence
|
||||
void attachAllSenseDevicesFromSpecsReq1(
|
||||
std::shared_ptr<AttachAllSenseDevicesFromSpecsReq> context,
|
||||
bool success, std::shared_ptr<device::DeviceAttachmentSpec> spec
|
||||
)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
std::cerr << __func__ << ": Failed to attach device: "
|
||||
<< spec->deviceIdentifier << "\n";
|
||||
}
|
||||
|
||||
if (!context->loop.incrementSuccessOrFailureAndTestForCompletionDueTo(
|
||||
success))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (OptionParser::getOptions().verbose)
|
||||
{
|
||||
std::cout << __func__ << ": " << context->loop.nSucceeded.load()
|
||||
<< " devices attached, "
|
||||
<< context->loop.nFailed.load() << " devices failed\n";
|
||||
}
|
||||
|
||||
context->originalCbFn(context->loop);
|
||||
}
|
||||
|
||||
public:
|
||||
AsynchronousLoop loop;
|
||||
};
|
||||
|
||||
void SenseApiManager::attachAllSenseDevicesFromSpecsReq(
|
||||
attachAllSenseDevicesFromSpecsReqCbFn cb
|
||||
)
|
||||
{
|
||||
// Create the attachment request object to hold state and callbacks
|
||||
auto request = std::make_shared<AttachAllSenseDevicesFromSpecsReq>(
|
||||
device::DeviceManager::deviceAttachmentSpecs.size(), std::move(cb));
|
||||
|
||||
for (const auto& spec : device::DeviceManager::deviceAttachmentSpecs)
|
||||
{
|
||||
try {
|
||||
attachSenseDeviceReq(spec,
|
||||
[spec, &loop, &bridge](bool success) -> void
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
std::cerr << __func__ << ": Failed to attach device: "
|
||||
<< spec->deviceIdentifier << "\n";
|
||||
}
|
||||
|
||||
if (!loop.incrementSuccessOrFailureAndTestForCompletionDueTo(
|
||||
success))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << __func__ << ": " << loop.nSucceeded.load()
|
||||
<< " devices attached, "
|
||||
<< loop.nFailed.load() << " devices failed\n";
|
||||
|
||||
bridge.setAsyncOperationComplete();
|
||||
});
|
||||
attachSenseDeviceReq(
|
||||
spec,
|
||||
std::bind(
|
||||
&AttachAllSenseDevicesFromSpecsReq::attachAllSenseDevicesFromSpecsReq1,
|
||||
request.get(), request,
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << __func__ << ": Exception: " << e.what() << "\n";
|
||||
if (loop.incrementSuccessOrFailureAndTestForCompletionDueTo(false))
|
||||
{ bridge.setAsyncOperationComplete(); }
|
||||
if (request->loop.incrementSuccessOrFailureAndTestForCompletionDueTo(false))
|
||||
{ cb(request->loop); }
|
||||
}
|
||||
}
|
||||
|
||||
/* Bridge the async op here. */
|
||||
bridge.waitForAsyncOperationCompleteOrIoServiceStopped();
|
||||
if (bridge.exitedBecauseIoServiceStopped())
|
||||
{
|
||||
/* Return early because the io_service is stopped. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!loop.isComplete())
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string(__func__) + ": Failed to get through all devices");
|
||||
}
|
||||
|
||||
std::cout << __func__ << ": " << loop.nSucceeded.load() << "/"
|
||||
<< loop.nTotal << " devices attached, "
|
||||
<< loop.nFailed.load() << "/" << loop.nTotal
|
||||
<< " devices failed\n";
|
||||
}
|
||||
|
||||
void SenseApiManager::detachAllSenseDevicesReq(void)
|
||||
class SenseApiManager::DetachAllSenseDevicesReq
|
||||
: public AttachAllSenseDevicesFromSpecsReq
|
||||
{
|
||||
auto self = ComponentThread::getSelf();
|
||||
AsynchronousBridge bridge(self->getIoService());
|
||||
AsynchronousLoop loop(device::DeviceManager::deviceAttachmentSpecs.size());
|
||||
public:
|
||||
using AttachAllSenseDevicesFromSpecsReq::AttachAllSenseDevicesFromSpecsReq;
|
||||
|
||||
void detachAllSenseDevicesReq1(
|
||||
std::shared_ptr<DetachAllSenseDevicesReq> context,
|
||||
bool success, std::shared_ptr<device::DeviceAttachmentSpec> spec
|
||||
)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
std::cerr << __func__ << ": Failed to detach device: "
|
||||
<< spec->deviceIdentifier << "\n";
|
||||
}
|
||||
|
||||
if (!context->loop.incrementSuccessOrFailureAndTestForCompletionDueTo(
|
||||
success))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (OptionParser::getOptions().verbose)
|
||||
{
|
||||
std::cout << __func__ << ": " << context->loop.nSucceeded.load()
|
||||
<< " devices detached, "
|
||||
<< context->loop.nFailed.load() << " devices failed\n";
|
||||
}
|
||||
|
||||
context->originalCbFn(context->loop);
|
||||
}
|
||||
};
|
||||
|
||||
void SenseApiManager::detachAllSenseDevicesReq(
|
||||
detachAllSenseDevicesReqCbFn cb
|
||||
)
|
||||
{
|
||||
auto request = std::make_shared<DetachAllSenseDevicesReq>(
|
||||
device::DeviceManager::deviceAttachmentSpecs.size(), std::move(cb));
|
||||
|
||||
for (const auto& spec : device::DeviceManager::deviceAttachmentSpecs)
|
||||
{
|
||||
try {
|
||||
detachSenseDeviceReq(spec,
|
||||
[spec, &loop, &bridge](bool success) -> void
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
std::cerr << __func__ << ": Failed to detach device: "
|
||||
<< spec->deviceIdentifier << "\n";
|
||||
}
|
||||
|
||||
if (!loop.incrementSuccessOrFailureAndTestForCompletionDueTo(
|
||||
success))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << __func__ << ": " << loop.nSucceeded.load()
|
||||
<< " devices detached, "
|
||||
<< loop.nFailed.load() << " devices failed\n";
|
||||
|
||||
bridge.setAsyncOperationComplete();
|
||||
});
|
||||
detachSenseDeviceReq(
|
||||
spec,
|
||||
std::bind(
|
||||
&DetachAllSenseDevicesReq::detachAllSenseDevicesReq1,
|
||||
request.get(), request,
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << __func__ << ": Exception: " << e.what() << "\n";
|
||||
if (loop.incrementSuccessOrFailureAndTestForCompletionDueTo(false))
|
||||
{ bridge.setAsyncOperationComplete(); }
|
||||
if (request->loop.incrementSuccessOrFailureAndTestForCompletionDueTo(false))
|
||||
{ cb(request->loop); }
|
||||
}
|
||||
}
|
||||
|
||||
/* Bridge the async op here. */
|
||||
bridge.waitForAsyncOperationCompleteOrIoServiceStopped();
|
||||
if (bridge.exitedBecauseIoServiceStopped())
|
||||
{
|
||||
/* Return early because the io_service is stopped. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!loop.isComplete())
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string(__func__) + ": Failed to get through all devices");
|
||||
}
|
||||
|
||||
std::cout << __func__ << ": " << loop.nSucceeded.load() << "/"
|
||||
<< loop.nTotal << " devices detached, "
|
||||
<< loop.nFailed.load() << "/" << loop.nTotal
|
||||
<< " devices failed\n";
|
||||
}
|
||||
|
||||
} // namespace sense_api
|
||||
|
||||
Reference in New Issue
Block a user