summaryrefslogtreecommitdiff
path: root/src/components/utils/include
diff options
context:
space:
mode:
authorAsen Kirov <akirov@luxoft.com>2015-10-22 15:42:18 +0300
committerAsen Kirov <akirov@luxoft.com>2015-10-22 15:42:18 +0300
commit2b76d0ccac3ceb0e6568fef95bd874b7d7a598d7 (patch)
treedd72d81bdf424096a696437385298f4dae36f04c /src/components/utils/include
parentcee517d5ff7f7aeecef453460ebeef79bdcef4e1 (diff)
downloadsdl_core-2b76d0ccac3ceb0e6568fef95bd874b7d7a598d7.tar.gz
Fix race condition in Singleton and Application Manager failure to stop
When SDL is started, but the HMI is not, and we try to register a mobile app (RegisterAppInterfaceRequest), then in this situation SDL can't be stopped with ctrl+C - it enters in an endless cycle. The reason for the problem is that we can't delete the AM, because the RequestController thread of AM is still running (waiting in a cycle for the HMI to respond). Also a second AM is created, because in the Singleton we set to 0 the instance pointer before deleting it and someone calls instance() before destroy() finishes, because there is no common lock. The separate locks create a race condition. The fix is to use a single mutex for the Singleton methods, introduce a is_stopping_ flag in AM, set it to true in AM's Stop() method, and also destroy RequestController's thread pool there. Then check stop flag in RegisterAppInterfaceRequest::Run() and exit the HMI waiting cycle there.
Diffstat (limited to 'src/components/utils/include')
-rw-r--r--src/components/utils/include/utils/singleton.h17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/components/utils/include/utils/singleton.h b/src/components/utils/include/utils/singleton.h
index 41face4f2f..fff7294d1c 100644
--- a/src/components/utils/include/utils/singleton.h
+++ b/src/components/utils/include/utils/singleton.h
@@ -111,18 +111,24 @@ class Singleton {
static T** instance_pointer();
static Deleter* deleter();
+
+ static sync_primitives::Lock lock_;
};
+
+template<typename T, class Deleter>
+sync_primitives::Lock Singleton<T, Deleter>::lock_;
+
+
template<typename T, class Deleter>
T* Singleton<T, Deleter>::instance() {
- static sync_primitives::Lock lock;
T* local_instance;
atomic_pointer_assign(local_instance, *instance_pointer());
memory_barrier();
if (!local_instance) {
- lock.Acquire();
+ lock_.Acquire();
local_instance = *instance_pointer();
if (!local_instance) {
local_instance = new T();
@@ -130,7 +136,7 @@ T* Singleton<T, Deleter>::instance() {
atomic_pointer_assign(*instance_pointer(), local_instance);
deleter()->grab(local_instance);
}
- lock.Release();
+ lock_.Release();
}
return local_instance;
@@ -138,14 +144,13 @@ T* Singleton<T, Deleter>::instance() {
template<typename T, class Deleter>
void Singleton<T, Deleter>::destroy() {
- static sync_primitives::Lock lock;
T* local_instance;
atomic_pointer_assign(local_instance, *instance_pointer());
memory_barrier();
if (local_instance) {
- lock.Acquire();
+ lock_.Acquire();
local_instance = *instance_pointer();
if (local_instance) {
atomic_pointer_assign(*instance_pointer(), 0);
@@ -153,7 +158,7 @@ void Singleton<T, Deleter>::destroy() {
delete local_instance;
deleter()->grab(0);
}
- lock.Release();
+ lock_.Release();
}
}