summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrii Kalinich <AKalinich@luxoft.com>2019-09-26 14:41:19 -0400
committerAndrii Kalinich <AKalinich@luxoft.com>2019-09-27 11:35:31 -0400
commit46e8b4a9badea2e5bd4e9d06bdbb3be089e26e77 (patch)
tree608d9aaf92599bdf26ff01330a212a5613805d18
parent35e6a7ec5bbcb27bd972a2db07a18c2294b1bc0c (diff)
downloadsdl_core-fix/fix_random_sdl_crash.tar.gz
Fix SDL crash on app service unpublishingfix/fix_random_sdl_crash
There was found an unsafe work with STL map in AppServiceManager - during service unpublishing there might be a possibility when component iterates over published_services_ and another function indirectly erases the same element from the same map what may cause an undefined behavior during iteration over the map. To make this safer - iteration over the map and erasure of element in the map were splitted onto two separate atomic actions.
-rw-r--r--src/components/application_manager/src/app_service_manager.cc18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/components/application_manager/src/app_service_manager.cc b/src/components/application_manager/src/app_service_manager.cc
index a85921a8cd..afcc7ae1dd 100644
--- a/src/components/application_manager/src/app_service_manager.cc
+++ b/src/components/application_manager/src/app_service_manager.cc
@@ -223,13 +223,21 @@ bool AppServiceManager::UnpublishAppService(const std::string service_id) {
void AppServiceManager::UnpublishServices(const uint32_t connection_key) {
LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_DEBUG(logger_, "Unpublishing all app services: " << connection_key);
- sync_primitives::AutoLock lock(published_services_lock_);
- for (auto it = published_services_.begin(); it != published_services_.end();
- ++it) {
- if (it->second.connection_key == connection_key) {
- UnpublishAppService(it->first);
+
+ std::list<std::string> app_published_services;
+ {
+ sync_primitives::AutoLock lock(published_services_lock_);
+ for (auto it = published_services_.begin(); it != published_services_.end();
+ ++it) {
+ if (it->second.connection_key == connection_key) {
+ app_published_services.push_back(it->first);
+ }
}
}
+
+ for (auto& service_id : app_published_services) {
+ UnpublishAppService(service_id);
+ }
}
void AppServiceManager::OnAppActivated(ApplicationConstSharedPtr app) {