livoxGen1🐛 Call stop() on all producers before deleting in _exit
This commit is contained in:
@@ -14,7 +14,47 @@ namespace smo::stim_buff::lcamera_buff {
|
|||||||
const SmoCallbacks *lcameraBuffSmoHooksPtr = nullptr;
|
const SmoCallbacks *lcameraBuffSmoHooksPtr = nullptr;
|
||||||
SmoThreadingModelDesc lcameraBuffThreadingModelDesc;
|
SmoThreadingModelDesc lcameraBuffThreadingModelDesc;
|
||||||
LcameraDevDllState lcameraDevDll;
|
LcameraDevDllState lcameraDevDll;
|
||||||
std::vector<std::shared_ptr<YuvStimProducer>> attachedStimulusProducers;
|
std::vector<std::shared_ptr<YuvStimProducer>> managedStimulusProducers;
|
||||||
|
|
||||||
|
void addManagedStimulusProducer(
|
||||||
|
const std::shared_ptr<YuvStimProducer>& producer)
|
||||||
|
{
|
||||||
|
managedStimulusProducers.push_back(producer);
|
||||||
|
producer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
sscl::co::ViralNonPostingInvoker<void> removeManagedStimulusProducerIfUnused(
|
||||||
|
const std::shared_ptr<YuvStimProducer>& producer)
|
||||||
|
{
|
||||||
|
if (!producer) {
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!producer->attachedStimulusBuffers.empty()) {
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
producer->stop();
|
||||||
|
|
||||||
|
managedStimulusProducers.erase(
|
||||||
|
std::remove_if(
|
||||||
|
managedStimulusProducers.begin(),
|
||||||
|
managedStimulusProducers.end(),
|
||||||
|
[&producer](const std::shared_ptr<YuvStimProducer>& candidate)
|
||||||
|
{
|
||||||
|
return candidate == producer;
|
||||||
|
}),
|
||||||
|
managedStimulusProducers.end());
|
||||||
|
|
||||||
|
const std::shared_ptr<lcamera_dev::CameraSession> deviceSession =
|
||||||
|
producer->deviceSession;
|
||||||
|
|
||||||
|
if (deviceSession) {
|
||||||
|
co_await (*lcameraDevDll.lcameraDev_releaseDeviceCReq)(deviceSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
producer->deviceSession.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void LcameraDevDllState::DlCloser::operator()(void *handle)
|
void LcameraDevDllState::DlCloser::operator()(void *handle)
|
||||||
{
|
{
|
||||||
@@ -37,7 +77,7 @@ std::shared_ptr<YuvStimProducer> findStimProducerByCameraId(
|
|||||||
const std::string& resolvedCameraId)
|
const std::string& resolvedCameraId)
|
||||||
{
|
{
|
||||||
for (const std::shared_ptr<YuvStimProducer>& producer :
|
for (const std::shared_ptr<YuvStimProducer>& producer :
|
||||||
attachedStimulusProducers)
|
managedStimulusProducers)
|
||||||
{
|
{
|
||||||
assert(producer != nullptr);
|
assert(producer != nullptr);
|
||||||
if (producer->resolvedCameraId == resolvedCameraId) {
|
if (producer->resolvedCameraId == resolvedCameraId) {
|
||||||
@@ -83,6 +123,16 @@ bool validateAttachRequest(
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
void stopAllManagedProducersBeforeFinalize()
|
||||||
|
{
|
||||||
|
for (const std::shared_ptr<YuvStimProducer>& producer :
|
||||||
|
managedStimulusProducers)
|
||||||
|
{
|
||||||
|
assert(producer != nullptr);
|
||||||
|
producer->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void loadLcameraDevSymbols()
|
void loadLcameraDevSymbols()
|
||||||
{
|
{
|
||||||
lcameraDevDll.lcameraDev_main = reinterpret_cast<lcameraDev_mainFn *>(
|
lcameraDevDll.lcameraDev_main = reinterpret_cast<lcameraDev_mainFn *>(
|
||||||
@@ -171,7 +221,7 @@ attachByCreatingProducer(
|
|||||||
parsedParams,
|
parsedParams,
|
||||||
configuredMode);
|
configuredMode);
|
||||||
|
|
||||||
attachedStimulusProducers.push_back(producer);
|
addManagedStimulusProducer(producer);
|
||||||
|
|
||||||
co_return co_await attachChannelBufferToProducer(desc, producer);
|
co_return co_await attachChannelBufferToProducer(desc, producer);
|
||||||
}
|
}
|
||||||
@@ -212,14 +262,8 @@ sscl::co::ViralNonPostingInvoker<int> lcameraBuff_initializeCInd()
|
|||||||
|
|
||||||
sscl::co::ViralNonPostingInvoker<int> lcameraBuff_finalizeCInd()
|
sscl::co::ViralNonPostingInvoker<int> lcameraBuff_finalizeCInd()
|
||||||
{
|
{
|
||||||
for (const std::shared_ptr<YuvStimProducer>& producer :
|
stopAllManagedProducersBeforeFinalize();
|
||||||
attachedStimulusProducers)
|
managedStimulusProducers.clear();
|
||||||
{
|
|
||||||
assert(producer != nullptr);
|
|
||||||
producer->deviceSession.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
attachedStimulusProducers.clear();
|
|
||||||
|
|
||||||
if (lcameraDevDll.lcameraDev_exit) {
|
if (lcameraDevDll.lcameraDev_exit) {
|
||||||
(*lcameraDevDll.lcameraDev_exit)();
|
(*lcameraDevDll.lcameraDev_exit)();
|
||||||
@@ -284,26 +328,11 @@ lcameraBuff_detachDeviceCReq(
|
|||||||
|
|
||||||
producer->destroyAttachedStimulusBuffer(stimBuffer);
|
producer->destroyAttachedStimulusBuffer(stimBuffer);
|
||||||
|
|
||||||
const std::shared_ptr<lcamera_dev::CameraSession> deviceSession =
|
|
||||||
producer->deviceSession;
|
|
||||||
|
|
||||||
co_await (*lcameraDevDll.lcameraDev_releaseDeviceCReq)(deviceSession);
|
|
||||||
|
|
||||||
if (!producer->attachedStimulusBuffers.empty()) {
|
if (!producer->attachedStimulusBuffers.empty()) {
|
||||||
co_return StimBuffDeviceOpResult{true, desc};
|
co_return StimBuffDeviceOpResult{true, desc};
|
||||||
}
|
}
|
||||||
|
|
||||||
attachedStimulusProducers.erase(
|
co_await removeManagedStimulusProducerIfUnused(producer);
|
||||||
std::remove_if(
|
|
||||||
attachedStimulusProducers.begin(),
|
|
||||||
attachedStimulusProducers.end(),
|
|
||||||
[&producer](const std::shared_ptr<YuvStimProducer>& candidate)
|
|
||||||
{
|
|
||||||
return candidate == producer;
|
|
||||||
}),
|
|
||||||
attachedStimulusProducers.end());
|
|
||||||
|
|
||||||
producer->deviceSession.reset();
|
|
||||||
|
|
||||||
co_return StimBuffDeviceOpResult{true, desc};
|
co_return StimBuffDeviceOpResult{true, desc};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,13 @@ struct LcameraDevDllState
|
|||||||
extern const SmoCallbacks *lcameraBuffSmoHooksPtr;
|
extern const SmoCallbacks *lcameraBuffSmoHooksPtr;
|
||||||
extern SmoThreadingModelDesc lcameraBuffThreadingModelDesc;
|
extern SmoThreadingModelDesc lcameraBuffThreadingModelDesc;
|
||||||
extern LcameraDevDllState lcameraDevDll;
|
extern LcameraDevDllState lcameraDevDll;
|
||||||
extern std::vector<std::shared_ptr<YuvStimProducer>> attachedStimulusProducers;
|
extern std::vector<std::shared_ptr<YuvStimProducer>> managedStimulusProducers;
|
||||||
|
|
||||||
|
void addManagedStimulusProducer(
|
||||||
|
const std::shared_ptr<YuvStimProducer>& producer);
|
||||||
|
|
||||||
|
sscl::co::ViralNonPostingInvoker<void> removeManagedStimulusProducerIfUnused(
|
||||||
|
const std::shared_ptr<YuvStimProducer>& producer);
|
||||||
|
|
||||||
std::shared_ptr<YuvStimProducer> findStimProducerByCameraId(
|
std::shared_ptr<YuvStimProducer> findStimProducerByCameraId(
|
||||||
const std::string& resolvedCameraId);
|
const std::string& resolvedCameraId);
|
||||||
|
|||||||
@@ -235,10 +235,10 @@ TEST_F(LcameraBuffConfigureHilTest, AttachThreeYuvChannelsWithOptPlanar480p)
|
|||||||
++expectedBufferCount;
|
++expectedBufferCount;
|
||||||
|
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
smo::stim_buff::lcamera_buff::attachedStimulusProducers.size(),
|
smo::stim_buff::lcamera_buff::managedStimulusProducers.size(),
|
||||||
1u);
|
1u);
|
||||||
producer = smo::stim_buff::lcamera_buff
|
producer = smo::stim_buff::lcamera_buff
|
||||||
::attachedStimulusProducers.front();
|
::managedStimulusProducers.front();
|
||||||
ASSERT_TRUE(producer != nullptr);
|
ASSERT_TRUE(producer != nullptr);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
producer->attachedStimulusBuffers.size(),
|
producer->attachedStimulusBuffers.size(),
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const SmoCallbacks *smoHooksPtr = nullptr;
|
|||||||
SmoThreadingModelDesc smoThreadingModelDesc;
|
SmoThreadingModelDesc smoThreadingModelDesc;
|
||||||
|
|
||||||
// Local collection of stimulus producers
|
// Local collection of stimulus producers
|
||||||
std::vector<std::shared_ptr<StimulusProducer>> attachedStimulusProducers;
|
std::vector<std::shared_ptr<StimulusProducer>> managedStimulusProducers;
|
||||||
|
|
||||||
LivoxProto1DllState::LivoxProto1DllState()
|
LivoxProto1DllState::LivoxProto1DllState()
|
||||||
: dlopenHandle(nullptr, DlCloser),
|
: dlopenHandle(nullptr, DlCloser),
|
||||||
@@ -46,7 +46,7 @@ LivoxProto1DllState livoxProto1;
|
|||||||
std::shared_ptr<StimulusProducer> getStimulusProducer(
|
std::shared_ptr<StimulusProducer> getStimulusProducer(
|
||||||
const std::shared_ptr<device::DeviceAttachmentSpec> &spec)
|
const std::shared_ptr<device::DeviceAttachmentSpec> &spec)
|
||||||
{
|
{
|
||||||
for (const auto &stimProducer : attachedStimulusProducers)
|
for (const auto &stimProducer : managedStimulusProducers)
|
||||||
{
|
{
|
||||||
if (livoxProto1::comms::deviceIdentifiersEqual(
|
if (livoxProto1::comms::deviceIdentifiersEqual(
|
||||||
stimProducer->deviceAttachmentSpec->deviceSelector,
|
stimProducer->deviceAttachmentSpec->deviceSelector,
|
||||||
@@ -189,6 +189,8 @@ LivoxProviderParams parseLivoxProviderParams(
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr size_t MAX_STIM_PRODUCERS_PER_DEVICE = 2;
|
||||||
|
|
||||||
// Helper method to ensure StimBuffer is attached
|
// Helper method to ensure StimBuffer is attached
|
||||||
// Returns true if successful, false on error
|
// Returns true if successful, false on error
|
||||||
bool ensureStimBufferAttachedWithoutDuplicates(
|
bool ensureStimBufferAttachedWithoutDuplicates(
|
||||||
@@ -224,9 +226,125 @@ bool ensureStimBufferAttachedWithoutDuplicates(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addManagedStimulusProducer(
|
||||||
|
const std::shared_ptr<PcloudStimulusProducer> &producer,
|
||||||
|
const std::shared_ptr<livoxProto1::Device> &device)
|
||||||
|
{
|
||||||
|
if (!producer || !device) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::string(__func__) + ": producer and device must be non-null");
|
||||||
|
}
|
||||||
|
|
||||||
|
device->nAttachedStimulusProducers++;
|
||||||
|
if (device->nAttachedStimulusProducers > MAX_STIM_PRODUCERS_PER_DEVICE)
|
||||||
|
{
|
||||||
|
device->nAttachedStimulusProducers--;
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::string(__func__) + ": Each LivoxGen1 device can only have "
|
||||||
|
"at most two StimulusProducers attached to it. Found "
|
||||||
|
+ std::to_string(device->nAttachedStimulusProducers + 1) + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
managedStimulusProducers.push_back(producer);
|
||||||
|
if (false
|
||||||
|
/*managedStimulusProducers.size() >= 2*nDevicesKnownToGen1Lib */)
|
||||||
|
{
|
||||||
|
/** TODO:
|
||||||
|
* It would be nice to add an nDevicesKnownToGen1Lib counter, and
|
||||||
|
* then add a check here to ensure that
|
||||||
|
* managedStimulusProducers.size() is always less than or equal to
|
||||||
|
* 2*nDevicesKnownToGen1Lib.
|
||||||
|
*
|
||||||
|
* (2 stim producers per device).
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::string(__func__) + ": Number of StimulusProducers attached "
|
||||||
|
"to LivoxGen1 devices known to the library ("
|
||||||
|
+ std::to_string(managedStimulusProducers.size())
|
||||||
|
+ ") is greater than "
|
||||||
|
"expected. Lib knows about "
|
||||||
|
+ std::to_string(nDevicesKnownToGen1Lib) + " devices, "
|
||||||
|
"so there should be at most "
|
||||||
|
+ std::to_string(2*nDevicesKnownToGen1Lib)
|
||||||
|
+ " StimulusProducers attached to devices.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
producer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
sscl::co::ViralNonPostingInvoker<bool> removeManagedStimulusProducerIfUnused(
|
||||||
|
const std::shared_ptr<PcloudStimulusProducer> &producer,
|
||||||
|
const std::shared_ptr<sscl::ComponentThread> &/*componentThread*/)
|
||||||
|
{
|
||||||
|
if (!producer) {
|
||||||
|
co_return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!producer->attachedStimulusBuffers.empty()) {
|
||||||
|
co_return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No other buffers - stop and remove StimProducer
|
||||||
|
producer->stop();
|
||||||
|
|
||||||
|
auto it = std::find_if(
|
||||||
|
managedStimulusProducers.begin(),
|
||||||
|
managedStimulusProducers.end(),
|
||||||
|
[&producer](const std::shared_ptr<StimulusProducer> &candidate)
|
||||||
|
{
|
||||||
|
/** FIXME:
|
||||||
|
* When we implement the ImuStimulusProducer, we need to make
|
||||||
|
* sure we handle that properly here.
|
||||||
|
*/
|
||||||
|
auto pcloudProducer =
|
||||||
|
std::dynamic_pointer_cast<PcloudStimulusProducer>(candidate);
|
||||||
|
return pcloudProducer && pcloudProducer == producer;
|
||||||
|
});
|
||||||
|
if (it != managedStimulusProducers.end()) {
|
||||||
|
managedStimulusProducers.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!producer->device) {
|
||||||
|
co_return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (producer->device->nAttachedStimulusProducers > 0) {
|
||||||
|
producer->device->nAttachedStimulusProducers--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (producer->device->nAttachedStimulusProducers > 0) {
|
||||||
|
co_return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool destroyed = co_await (*livoxProto1.livoxProto1_destroyDeviceCReq)(
|
||||||
|
producer->device);
|
||||||
|
if (!destroyed)
|
||||||
|
{
|
||||||
|
std::cerr << __func__ << ": Failed to destroy dev "
|
||||||
|
"device " << producer->deviceAttachmentSpec->deviceSelector
|
||||||
|
<< " for stim producer.\n";
|
||||||
|
|
||||||
|
co_return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
co_return true;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr size_t MAX_STIM_PRODUCERS_PER_DEVICE = 2;
|
void stopAllManagedProducersBeforeFinalize()
|
||||||
|
{
|
||||||
|
for (const auto &producer : managedStimulusProducers)
|
||||||
|
{
|
||||||
|
if (!producer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
producer->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool validateAttachRequest(
|
bool validateAttachRequest(
|
||||||
const std::shared_ptr<device::DeviceAttachmentSpec> &desc)
|
const std::shared_ptr<device::DeviceAttachmentSpec> &desc)
|
||||||
@@ -458,44 +576,7 @@ attachByCreatingProducer(
|
|||||||
desc, deviceResult.device,
|
desc, deviceResult.device,
|
||||||
formatDesc, nDgramsPerFrame);
|
formatDesc, nDgramsPerFrame);
|
||||||
|
|
||||||
deviceResult.device->nAttachedStimulusProducers++;
|
addManagedStimulusProducer(pcloudDataProducer, deviceResult.device);
|
||||||
if (deviceResult.device->nAttachedStimulusProducers
|
|
||||||
> MAX_STIM_PRODUCERS_PER_DEVICE)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
std::string(__func__) + ": Each LivoxGen1 device can only have "
|
|
||||||
"at most two StimulusProducers attached to it. Found "
|
|
||||||
+ std::to_string(deviceResult.device->nAttachedStimulusProducers)
|
|
||||||
+ ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
attachedStimulusProducers.push_back(pcloudDataProducer);
|
|
||||||
if (false
|
|
||||||
/*attachedStimulusProducers.size() >= 2*nDevicesKnownToGen1Lib */)
|
|
||||||
{
|
|
||||||
/** TODO:
|
|
||||||
* It would be nice to add an nDevicesKnownToGen1Lib counter, and
|
|
||||||
* then add a check here to ensure that
|
|
||||||
* attachedStimulusProducers.size() is always less than or equal to
|
|
||||||
* 2*nDevicesKnownToGen1Lib.
|
|
||||||
*
|
|
||||||
* (2 stim producers per device).
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
throw std::runtime_error(
|
|
||||||
std::string(__func__) + ": Number of StimulusProducers attached "
|
|
||||||
"to LivoxGen1 devices known to the library ("
|
|
||||||
+ std::to_string(attachedStimulusProducers.size())
|
|
||||||
+ ") is greater than "
|
|
||||||
"expected. Lib knows about "
|
|
||||||
+ std::to_string(nDevicesKnownToGen1Lib) + " devices, "
|
|
||||||
"so there should be at most "
|
|
||||||
+ std::to_string(2*nDevicesKnownToGen1Lib)
|
|
||||||
+ " StimulusProducers attached to devices.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
pcloudDataProducer->start();
|
|
||||||
|
|
||||||
// Ensure StimBuffer is attached
|
// Ensure StimBuffer is attached
|
||||||
co_return co_await attachBufferAndEnablePcloud(
|
co_return co_await attachBufferAndEnablePcloud(
|
||||||
@@ -592,8 +673,8 @@ livoxGen1_detachDeviceCReq(
|
|||||||
|
|
||||||
// Add 5ms delay before destroying device
|
// Add 5ms delay before destroying device
|
||||||
|
|
||||||
// Helper method to delay and then call destroyDeviceReq
|
// Helper method to delay and then call destroyDeviceReq
|
||||||
// Initialize timer with LivoxGen1 metadata io_context
|
// Initialize timer with LivoxGen1 metadata io_context
|
||||||
boost::asio::deadline_timer commandDelayTimer(
|
boost::asio::deadline_timer commandDelayTimer(
|
||||||
requestComponentThread->getIoContext());
|
requestComponentThread->getIoContext());
|
||||||
co_await adapters::boostAsio::getDeadlineTimerAReqAwaiter(
|
co_await adapters::boostAsio::getDeadlineTimerAReqAwaiter(
|
||||||
@@ -601,40 +682,9 @@ livoxGen1_detachDeviceCReq(
|
|||||||
commandDelayTimer,
|
commandDelayTimer,
|
||||||
boost::posix_time::milliseconds(LIVOX_GEN1_DEVICE_COMMAND_DELAY_MS));
|
boost::posix_time::milliseconds(LIVOX_GEN1_DEVICE_COMMAND_DELAY_MS));
|
||||||
|
|
||||||
// No other buffers - stop and remove StimProducer
|
const bool removedOk = co_await removeManagedStimulusProducerIfUnused(
|
||||||
stimProducer->stop();
|
stimProducer, requestComponentThread);
|
||||||
// Remove stimulus producer from collection before destroying device
|
if (!removedOk) {
|
||||||
stimProducer->device->nAttachedStimulusProducers--;
|
|
||||||
|
|
||||||
// Find and remove the producer from the collection by comparing device
|
|
||||||
auto it = std::find_if(
|
|
||||||
attachedStimulusProducers.begin(),
|
|
||||||
attachedStimulusProducers.end(),
|
|
||||||
[&stimProducer](const std::shared_ptr<StimulusProducer> &producer)
|
|
||||||
{
|
|
||||||
/** FIXME:
|
|
||||||
* When we implement the ImuStimulusProducer, we need to make
|
|
||||||
* sure we handle that properly here.
|
|
||||||
*/
|
|
||||||
auto pcloudProducer =
|
|
||||||
std::dynamic_pointer_cast<PcloudStimulusProducer>(producer);
|
|
||||||
return pcloudProducer && pcloudProducer->device == stimProducer->device;
|
|
||||||
});
|
|
||||||
if (it != attachedStimulusProducers.end()) {
|
|
||||||
attachedStimulusProducers.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool destroyed = co_await (*livoxProto1.livoxProto1_destroyDeviceCReq)(
|
|
||||||
stimProducer->device);
|
|
||||||
if (!destroyed) {
|
|
||||||
std::cerr << __func__ << ": Failed to destroy dev "
|
|
||||||
"device " << desc->deviceSelector << " for stim "
|
|
||||||
"producer.\n";
|
|
||||||
|
|
||||||
/** NOTE:
|
|
||||||
* There's a decent argument for falling through here and still
|
|
||||||
* removing the stimulus producer from attachedStimulusProducers.
|
|
||||||
*/
|
|
||||||
co_return StimBuffDeviceOpResult{false, desc};
|
co_return StimBuffDeviceOpResult{false, desc};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -723,7 +773,9 @@ sscl::co::ViralNonPostingInvoker<int> livoxGen1_initializeCInd()
|
|||||||
|
|
||||||
sscl::co::ViralNonPostingInvoker<int> livoxGen1_finalizeCInd()
|
sscl::co::ViralNonPostingInvoker<int> livoxGen1_finalizeCInd()
|
||||||
{
|
{
|
||||||
attachedStimulusProducers.clear();
|
stopAllManagedProducersBeforeFinalize();
|
||||||
|
|
||||||
|
managedStimulusProducers.clear();
|
||||||
if (livoxProto1.livoxProto1_exit) {
|
if (livoxProto1.livoxProto1_exit) {
|
||||||
(*livoxProto1.livoxProto1_exit)();
|
(*livoxProto1.livoxProto1_exit)();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,15 @@ struct LivoxProviderParams
|
|||||||
|
|
||||||
extern const SmoCallbacks *smoHooksPtr;
|
extern const SmoCallbacks *smoHooksPtr;
|
||||||
extern SmoThreadingModelDesc smoThreadingModelDesc;
|
extern SmoThreadingModelDesc smoThreadingModelDesc;
|
||||||
extern std::vector<std::shared_ptr<StimulusProducer>> attachedStimulusProducers;
|
extern std::vector<std::shared_ptr<StimulusProducer>> managedStimulusProducers;
|
||||||
|
|
||||||
|
void addManagedStimulusProducer(
|
||||||
|
const std::shared_ptr<PcloudStimulusProducer> &producer,
|
||||||
|
const std::shared_ptr<livoxProto1::Device> &device);
|
||||||
|
|
||||||
|
sscl::co::ViralNonPostingInvoker<bool> removeManagedStimulusProducerIfUnused(
|
||||||
|
const std::shared_ptr<PcloudStimulusProducer> &producer,
|
||||||
|
const std::shared_ptr<sscl::ComponentThread> &componentThread);
|
||||||
|
|
||||||
std::shared_ptr<StimulusProducer> getStimulusProducer(
|
std::shared_ptr<StimulusProducer> getStimulusProducer(
|
||||||
const std::shared_ptr<device::DeviceAttachmentSpec> &spec);
|
const std::shared_ptr<device::DeviceAttachmentSpec> &spec);
|
||||||
|
|||||||
Reference in New Issue
Block a user