From 36eaea466ebe019de21940502653380e20a5862d Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sun, 9 Oct 2022 00:27:54 -0500 Subject: [PATCH] Garbage collect unused radar product manager instances --- .../scwx/qt/manager/radar_product_manager.cpp | 21 +++++++++++------ .../scwx/qt/model/radar_product_model.cpp | 23 ++++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp index 65ebe214..a5a6987f 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -50,8 +50,7 @@ static const std::string kDefaultLevel3Product_ {"N0B"}; static constexpr std::chrono::seconds kRetryInterval_ {15}; -// TODO: Find a way to garbage collect this -static std::unordered_map> +static std::unordered_map> instanceMap_; static std::mutex instanceMutex_; @@ -960,14 +959,22 @@ RadarProductManager::Instance(const std::string& radarSite) { std::lock_guard guard(instanceMutex_); - if (!instanceMap_.contains(radarSite)) + // Look up instance weak pointer + auto it = instanceMap_.find(radarSite); + if (it != instanceMap_.end()) { - instanceMap_[radarSite] = - std::make_shared(radarSite); - instanceCreated = true; + // Attempt to convert the weak pointer to a shared pointer. It may have + // been garbage collected. + instance = it->second.lock(); } - instance = instanceMap_[radarSite]; + // If no active instance was found, create a new one + if (instance == nullptr) + { + instance = std::make_shared(radarSite); + instanceMap_.insert_or_assign(radarSite, instance); + instanceCreated = true; + } } if (instanceCreated) diff --git a/scwx-qt/source/scwx/qt/model/radar_product_model.cpp b/scwx-qt/source/scwx/qt/model/radar_product_model.cpp index bb4ecebd..e2e158b0 100644 --- a/scwx-qt/source/scwx/qt/model/radar_product_model.cpp +++ b/scwx-qt/source/scwx/qt/model/radar_product_model.cpp @@ -50,17 +50,24 @@ RadarProductModelImpl::RadarProductModelImpl(RadarProductModel* self) : { logger_->debug("Adding radar site: {}", radarSite); - const QModelIndex rootIndex = - self_->createIndex(rootItem_->row(), 0, rootItem_.get()); - const int rootChildren = rootItem_->child_count(); + const QString radarSiteName {QString::fromStdString(radarSite)}; - self_->beginInsertRows(rootIndex, rootChildren, rootChildren); + // Find existing radar site item (e.g., KLSX, KEAX) + TreeItem* radarSiteItem = rootItem_->FindChild(0, radarSiteName); - TreeItem* radarSiteItem = - new TreeItem({QString::fromStdString(radarSite)}); - rootItem_->AppendChild(radarSiteItem); + if (radarSiteItem == nullptr) + { + const QModelIndex rootIndex = + self_->createIndex(rootItem_->row(), 0, rootItem_.get()); + const int rootChildren = rootItem_->child_count(); - self_->endInsertRows(); + self_->beginInsertRows(rootIndex, rootChildren, rootChildren); + + radarSiteItem = new TreeItem({radarSiteName}); + rootItem_->AppendChild(radarSiteItem); + + self_->endInsertRows(); + } connect( manager::RadarProductManager::Instance(radarSite).get(),