diff --git a/commonLibs/attachmentSupport/stimulusBuffer.cpp b/commonLibs/attachmentSupport/stimulusBuffer.cpp index 7388cd3..6e5956e 100644 --- a/commonLibs/attachmentSupport/stimulusBuffer.cpp +++ b/commonLibs/attachmentSupport/stimulusBuffer.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include namespace smo { @@ -14,37 +13,21 @@ namespace stim_buff { void StimulusBuffer::stop() { - shouldContinue.store(false); + { + SpinLock::Guard lock(shouldContinueLock); + shouldContinue = false; + } - // Set up a timeout bridge using the io_service - boost::asio::deadline_timer delayTimer(ioService); - AsynchronousBridge bridge(ioService); - - // Set up the delay to let in-flight operation finish - delayTimer.expires_from_now( - boost::posix_time::milliseconds(getStopDelayMs())); - - delayTimer.async_wait( - [&bridge](const boost::system::error_code& error) - { - (void)error; - - // Always signal complete, whether timeout expired or was cancelled - bridge.setAsyncOperationComplete(); - }); - - bridge.waitForAsyncOperationCompleteOrIoServiceStopped(); + // Cancel timer immediately + timer.cancel(); std::cout << __func__ << ": Stopped stimulus buffer for device " << deviceAttachmentSpec->deviceSelector << std::endl; - - // After delay, cancel timer and perform cleanup - timer.cancel(); } void StimulusBuffer::scheduleNextTimeout(int delayMs) { - if (!shouldContinue.load()) + if (!shouldContinue) { return; } // Schedule the next timeout using the provided delay @@ -70,7 +53,8 @@ void StimulusBuffer::onTimeout(const boost::system::error_code& error) return; } - if (!shouldContinue.load()) + SpinLock::Guard lock(shouldContinueLock); + if (!shouldContinue) { return; } /** EXPLANATION: @@ -85,6 +69,7 @@ void StimulusBuffer::onTimeout(const boost::system::error_code& error) * sleep for CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS ms before trying again. */ int nextWakeupDelayMs; + bool deferred = false; if (frameAssemblyRateLimiter.tryAcquire()) { nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS; @@ -97,13 +82,21 @@ void StimulusBuffer::onTimeout(const boost::system::error_code& error) */ stimFrameProductionTimesliceInd(); } - else { -std::cout << __func__ << ": Deferring frame production due to rate limit." << std::endl; - nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS; + else + { + nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS; + deferred = true; } // Schedule next timeout with the pre-determined duration scheduleNextTimeout(nextWakeupDelayMs); + + // We should be able to release the start/stop lock before printing here. + if (deferred) + { + std::cout << __func__ << ": Deferring frame by " << nextWakeupDelayMs + << "ms due to rate limit." << std::endl; + } } } // namespace stim_buff diff --git a/include/user/stimulusBuffer.h b/include/user/stimulusBuffer.h index ab991af..90ebd3a 100644 --- a/include/user/stimulusBuffer.h +++ b/include/user/stimulusBuffer.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "stimulusFrame.h" #include "deviceAttachmentSpec.h" @@ -74,7 +73,7 @@ public: std::cout << __func__ << ": Starting stimulus buffer for device " << deviceAttachmentSpec->deviceSelector << std::endl; - shouldContinue.store(true); + shouldContinue = true; scheduleNextTimeout(); } @@ -105,7 +104,8 @@ protected: private: boost::asio::io_service& ioService; - std::atomic shouldContinue; + SpinLock shouldContinueLock; + bool shouldContinue; boost::asio::deadline_timer timer; void scheduleNextTimeout(int delayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS);