livoxProto1:Device: Spinlock guard heartbeat stop() for races

This commit is contained in:
2025-11-07 21:36:00 -04:00
parent 7b092956c0
commit 1afa085fd4
2 changed files with 19 additions and 8 deletions
+15 -6
View File
@@ -1042,6 +1042,8 @@ void Device::startHeartbeat()
} }
// Register heartbeat ACK handler (cmd_set=0x00, cmd_id=0x03) // Register heartbeat ACK handler (cmd_set=0x00, cmd_id=0x03)
smo::SpinLock::Guard lock(heartbeatActiveLock);
registerUdpCommandHandler( registerUdpCommandHandler(
0x00, 0x03, discardHeartbeatAck, discoveredDevice.ipAddr); 0x00, 0x03, discardHeartbeatAck, discoveredDevice.ipAddr);
@@ -1057,14 +1059,16 @@ void Device::startHeartbeat()
void Device::stopHeartbeat() void Device::stopHeartbeat()
{ {
if (heartbeatActive.load())
{ {
smo::SpinLock::Guard lock(heartbeatActiveLock);
heartbeatActive.store(false); heartbeatActive.store(false);
if (heartbeatTimer) { unregisterUdpCommandHandler(0x00, 0x03, discoveredDevice.ipAddr);
heartbeatTimer->cancel();
} }
unregisterUdpCommandHandler(0x00, 0x03, discoveredDevice.ipAddr); if (heartbeatTimer) {
heartbeatTimer->cancel();
heartbeatTimer.reset();
} }
} }
@@ -1140,7 +1144,6 @@ void Device::sendHeartbeat()
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
heartbeatActive.store(false);
std::cerr << __func__ << ": Heartbeat send failed for device " std::cerr << __func__ << ": Heartbeat send failed for device "
<< discoveredDevice.deviceIdentifier << discoveredDevice.deviceIdentifier
<< ": " << e.what() << std::endl; << ": " << e.what() << std::endl;
@@ -1156,16 +1159,22 @@ void Device::onHeartbeatTimer(const boost::system::error_code& error)
if (error) if (error)
{ {
heartbeatActive.store(false);
std::cerr << "[" << __func__ << "] Heartbeat timer error for device " std::cerr << "[" << __func__ << "] Heartbeat timer error for device "
<< discoveredDevice.deviceIdentifier << discoveredDevice.deviceIdentifier
<< ": " << error.message() << std::endl; << ": " << error.message() << std::endl;
return; return;
} }
// Send next heartbeat // Send next heartbeat
{
smo::SpinLock::Guard lock(heartbeatActiveLock);
if (!heartbeatActive.load())
{ return; }
sendHeartbeat(); sendHeartbeat();
} }
}
uint32_t Device::getSubnetMaskFor(uint8_t nbits) uint32_t Device::getSubnetMaskFor(uint8_t nbits)
{ {
+2
View File
@@ -17,6 +17,7 @@
#include <boost/asio/posix/stream_descriptor.hpp> #include <boost/asio/posix/stream_descriptor.hpp>
#include "protocol.h" #include "protocol.h"
#include <callback.h> #include <callback.h>
#include <spinLock.h>
// Custom hash function for std::pair<uint8_t, uint8_t> // Custom hash function for std::pair<uint8_t, uint8_t>
namespace std { namespace std {
@@ -162,6 +163,7 @@ public:
// Heartbeat state // Heartbeat state
std::unique_ptr<boost::asio::deadline_timer> heartbeatTimer; std::unique_ptr<boost::asio::deadline_timer> heartbeatTimer;
std::atomic<bool> heartbeatActive; std::atomic<bool> heartbeatActive;
smo::SpinLock heartbeatActiveLock;
// Point cloud data state // Point cloud data state
std::atomic<bool> pcloudDataActive; std::atomic<bool> pcloudDataActive;