From 109cd9eb03fe26c7b94278fd7a1df2e5baab99d1 Mon Sep 17 00:00:00 2001 From: Hayodea Hekol Date: Fri, 31 Oct 2025 08:16:05 -0400 Subject: [PATCH] DevReattacher: Add 20ms sync delay during stop() This fixes the bug where in-flight async ops that were triggered by DevReattacher (such as livoxGen1_attachDeviceReq) that have unconditional delays in them would fire late, after the state var they rely upon had already been de-initialized. We use an async bridge to ensure that those ops get executed in the background and then resume execution after the delay. --- smocore/deviceManager/deviceReattacher.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/smocore/deviceManager/deviceReattacher.cpp b/smocore/deviceManager/deviceReattacher.cpp index bae5a9f..b8ff1e9 100644 --- a/smocore/deviceManager/deviceReattacher.cpp +++ b/smocore/deviceManager/deviceReattacher.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,24 @@ void DeviceReattacher::stop() { shouldContinue.store(false); timer.cancel(); + + // Set up a timeout bridge using Marionette thread's io_service + auto& mrnttIoService = ComponentThread::getMrntt()->getIoService(); + boost::asio::deadline_timer timeoutTimer(mrnttIoService); + AsynchronousBridge bridge(mrnttIoService); + + // Set up the timeout for ~10ms + timeoutTimer.expires_from_now(boost::posix_time::milliseconds(20)); + timeoutTimer.async_wait( + [&bridge](const boost::system::error_code& error) + { + (void)error; + + // Always signal complete, whether timeout expired or was cancelled + bridge.setAsyncOperationComplete(); + }); + + bridge.waitForAsyncOperationCompleteOrIoServiceStopped(); } void DeviceReattacher::scheduleNextTimeout()