Skip to content

Commit 6213205

Browse files
jonasvooon
authored andcommitted
Sys status: add mutex to M_VehicleInfo vehicles unordered map
1 parent b61ac7c commit 6213205

File tree

1 file changed

+49
-34
lines changed

1 file changed

+49
-34
lines changed

mavros/src/plugins/sys_status.cpp

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <vector>
2121
#include <unordered_map>
2222
#include <memory>
23+
#include <mutex>
24+
#include <shared_mutex>
2325
#include <utility>
2426

2527
#include "rcpputils/asserts.hpp"
@@ -678,6 +680,7 @@ class SystemStatusPlugin : public plugin::Plugin
678680

679681
using M_VehicleInfo = std::unordered_map<uint16_t, mavros_msgs::msg::VehicleInfo>;
680682
M_VehicleInfo vehicles;
683+
mutable std::shared_mutex vehicles_mutex;
681684

682685
/* -*- mid-level helpers -*- */
683686

@@ -687,8 +690,8 @@ class SystemStatusPlugin : public plugin::Plugin
687690
return sysid << 8 | compid;
688691
}
689692

690-
// Find or create vehicle info
691-
inline M_VehicleInfo::iterator find_or_create_vehicle_info(uint8_t sysid, uint8_t compid)
693+
// Caller must hold vehicles_mutex exclusively.
694+
inline M_VehicleInfo::iterator find_or_create_vehicle_info_unlocked(uint8_t sysid, uint8_t compid)
692695
{
693696
auto key = get_vehicle_key(sysid, compid);
694697
M_VehicleInfo::iterator ret = vehicles.find(key);
@@ -899,26 +902,28 @@ class SystemStatusPlugin : public plugin::Plugin
899902

900903
// XXX(vooon): i assume that UAS not interested in HBs from non-target system.
901904

902-
// Store generic info of all heartbeats seen
903-
auto it = find_or_create_vehicle_info(msg->sysid, msg->compid);
904-
905905
auto vehicle_mode = uas->str_mode_v10(hb.base_mode, hb.custom_mode);
906906
auto stamp = node->now();
907907

908-
// Update vehicle data
909-
it->second.header.stamp = stamp;
910-
it->second.available_info |= mavros_msgs::msg::VehicleInfo::HAVE_INFO_HEARTBEAT;
911-
it->second.autopilot = hb.autopilot;
912-
it->second.type = hb.type;
913-
it->second.system_status = hb.system_status;
914-
it->second.base_mode = hb.base_mode;
915-
it->second.custom_mode = hb.custom_mode;
916-
it->second.mode = vehicle_mode;
917-
918-
if (!(hb.base_mode & enum_value(MAV_MODE_FLAG::CUSTOM_MODE_ENABLED))) {
919-
it->second.mode_id = hb.base_mode;
920-
} else {
921-
it->second.mode_id = hb.custom_mode;
908+
{
909+
std::unique_lock<std::shared_mutex> lock(vehicles_mutex);
910+
auto it = find_or_create_vehicle_info_unlocked(msg->sysid, msg->compid);
911+
912+
// Update vehicle data
913+
it->second.header.stamp = stamp;
914+
it->second.available_info |= mavros_msgs::msg::VehicleInfo::HAVE_INFO_HEARTBEAT;
915+
it->second.autopilot = hb.autopilot;
916+
it->second.type = hb.type;
917+
it->second.system_status = hb.system_status;
918+
it->second.base_mode = hb.base_mode;
919+
it->second.custom_mode = hb.custom_mode;
920+
it->second.mode = vehicle_mode;
921+
922+
if (!(hb.base_mode & enum_value(MAV_MODE_FLAG::CUSTOM_MODE_ENABLED))) {
923+
it->second.mode_id = hb.base_mode;
924+
} else {
925+
it->second.mode_id = hb.custom_mode;
926+
}
922927
}
923928

924929
// Continue from here only if vehicle is my target
@@ -1094,21 +1099,26 @@ class SystemStatusPlugin : public plugin::Plugin
10941099
process_autopilot_version_normal(apv, msg->sysid, msg->compid);
10951100
}
10961101

1097-
// Store generic info of all autopilot seen
1098-
auto it = find_or_create_vehicle_info(msg->sysid, msg->compid);
1099-
1100-
// Update vehicle data
1101-
it->second.header.stamp = node->now();
1102-
it->second.available_info |= mavros_msgs::msg::VehicleInfo::HAVE_INFO_AUTOPILOT_VERSION;
1103-
it->second.capabilities = apv.capabilities;
1104-
it->second.flight_sw_version = apv.flight_sw_version;
1105-
it->second.middleware_sw_version = apv.middleware_sw_version;
1106-
it->second.os_sw_version = apv.os_sw_version;
1107-
it->second.board_version = apv.board_version;
1108-
it->second.flight_custom_version = custom_version_to_hex_string(apv.flight_custom_version);
1109-
it->second.vendor_id = apv.vendor_id;
1110-
it->second.product_id = apv.product_id;
1111-
it->second.uid = apv.uid;
1102+
auto stamp = node->now();
1103+
auto flight_custom_version = custom_version_to_hex_string(apv.flight_custom_version);
1104+
1105+
{
1106+
std::unique_lock<std::shared_mutex> lock(vehicles_mutex);
1107+
auto it = find_or_create_vehicle_info_unlocked(msg->sysid, msg->compid);
1108+
1109+
// Update vehicle data
1110+
it->second.header.stamp = stamp;
1111+
it->second.available_info |= mavros_msgs::msg::VehicleInfo::HAVE_INFO_AUTOPILOT_VERSION;
1112+
it->second.capabilities = apv.capabilities;
1113+
it->second.flight_sw_version = apv.flight_sw_version;
1114+
it->second.middleware_sw_version = apv.middleware_sw_version;
1115+
it->second.os_sw_version = apv.os_sw_version;
1116+
it->second.board_version = apv.board_version;
1117+
it->second.flight_custom_version = flight_custom_version;
1118+
it->second.vendor_id = apv.vendor_id;
1119+
it->second.product_id = apv.product_id;
1120+
it->second.uid = apv.uid;
1121+
}
11121122
}
11131123

11141124
void handle_battery_status(
@@ -1378,6 +1388,7 @@ class SystemStatusPlugin : public plugin::Plugin
13781388
publish_disconnection();
13791389

13801390
// Clear known vehicles
1391+
std::unique_lock<std::shared_mutex> lock(vehicles_mutex);
13811392
vehicles.clear();
13821393
}
13831394
}
@@ -1506,7 +1517,10 @@ class SystemStatusPlugin : public plugin::Plugin
15061517
mavros_msgs::srv::VehicleInfoGet::Response::SharedPtr res)
15071518
{
15081519
if (req->get_all) {
1520+
std::shared_lock<std::shared_mutex> lock(vehicles_mutex);
1521+
15091522
// Send all vehicles
1523+
res->vehicles.reserve(vehicles.size());
15101524
for (const auto & got : vehicles) {
15111525
res->vehicles.emplace_back(got.second);
15121526
}
@@ -1525,6 +1539,7 @@ class SystemStatusPlugin : public plugin::Plugin
15251539
}
15261540

15271541
uint16_t key = get_vehicle_key(req_sysid, req_compid);
1542+
std::shared_lock<std::shared_mutex> lock(vehicles_mutex);
15281543
auto it = vehicles.find(key);
15291544
if (it == vehicles.end()) {
15301545
// Vehicle not found

0 commit comments

Comments
 (0)