Fix shared_ptr cycles in C++ carla::Client

carla::client::detail::Simulator had a strong reference from
carla::client::LightManager, which meant that deleting the client-facing
carla::Client did not actually delete the Simulator object, meaning that
it remained connected. Fix that.
This commit is contained in:
anrp 2022-10-03 11:43:20 -04:00 committed by bernat
parent 38b020910a
commit 4e949228d4
5 changed files with 43 additions and 31 deletions

View File

@ -16,63 +16,75 @@ namespace client {
using LightGroup = rpc::LightState::LightGroup;
Color Light::GetColor() const {
assert(_light_manager && "No light_manager");
return _light_manager->GetColor(_id);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
return light_manager->GetColor(_id);
}
float Light::GetIntensity() const {
assert(_light_manager && "No light_manager");
return _light_manager->GetIntensity(_id);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
return light_manager->GetIntensity(_id);
}
LightGroup Light::GetLightGroup() const {
assert(_light_manager && "No light_manager");
return _light_manager->GetLightGroup(_id);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
return light_manager->GetLightGroup(_id);
}
LightState Light::GetLightState() const {
assert(_light_manager && "No light_manager");
return _light_manager->GetLightState(_id);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
return light_manager->GetLightState(_id);
}
bool Light::IsOn() const {
assert(_light_manager && "No light_manager");
return _light_manager->IsActive(_id) == true;
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
return light_manager->IsActive(_id) == true;
}
bool Light::IsOff() const {
assert(_light_manager && "No light_manager");
return _light_manager->IsActive(_id) == false;
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
return light_manager->IsActive(_id) == false;
}
void Light::SetColor(Color color) {
assert(_light_manager && "No light_manager");
_light_manager->SetColor(_id, color);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
light_manager->SetColor(_id, color);
}
void Light::SetIntensity(float intensity) {
assert(_light_manager && "No light_manager");
_light_manager->SetIntensity(_id, intensity);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
light_manager->SetIntensity(_id, intensity);
}
void Light::SetLightGroup(LightGroup group) {
assert(_light_manager && "No light_manager");
_light_manager->SetLightGroup(_id, group);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
light_manager->SetLightGroup(_id, group);
}
void Light::SetLightState(const LightState& state) {
assert(_light_manager && "No light_manager");
_light_manager->SetLightState(_id, state);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
light_manager->SetLightState(_id, state);
}
void Light::TurnOn() {
assert(_light_manager && "No light_manager");
_light_manager->SetActive(_id, true);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
light_manager->SetActive(_id, true);
}
void Light::TurnOff() {
assert(_light_manager && "No light_manager");
_light_manager->SetActive(_id, false);
auto light_manager = _light_manager.lock();
assert(light_manager && "No light_manager");
light_manager->SetActive(_id, false);
}

View File

@ -62,14 +62,14 @@ private:
friend class LightManager;
Light(SharedPtr<LightManager> light_manager,
Light(WeakPtr<LightManager> light_manager,
geom::Location location,
LightId id)
: _light_manager(light_manager),
_location (location),
_id (id) {}
SharedPtr<LightManager> _light_manager;
WeakPtr<LightManager> _light_manager;
geom::Location _location;
LightId _id;

View File

@ -22,7 +22,7 @@ LightManager::~LightManager(){
UpdateServerLightsState(true);
}
void LightManager::SetEpisode(detail::EpisodeProxy episode) {
void LightManager::SetEpisode(detail::WeakEpisodeProxy episode) {
_episode = episode;

View File

@ -43,7 +43,7 @@ public:
_dirty = other._dirty;
}
void SetEpisode(detail::EpisodeProxy episode);
void SetEpisode(detail::WeakEpisodeProxy episode);
std::vector<Light> GetAllLights(LightGroup type = LightGroup::None) const;
// TODO: std::vector<Light> GetAllLightsInRoad(RoadId id, LightGroup type = LightGroup::None);
@ -99,7 +99,7 @@ private:
std::unordered_map<LightId, LightState> _lights_changes;
std::unordered_map<LightId, Light> _lights;
detail::EpisodeProxy _episode;
detail::WeakEpisodeProxy _episode;
std::mutex _mutex;

View File

@ -134,7 +134,7 @@ namespace detail {
if (!GetEpisodeSettings().synchronous_mode) {
WaitForTick(_client.GetTimeout());
}
_light_manager->SetEpisode(EpisodeProxy{shared_from_this()});
_light_manager->SetEpisode(WeakEpisodeProxy{shared_from_this()});
}
return EpisodeProxy{shared_from_this()};
}