Globals in LogSystem adjusted to use in lib constructor 98/35798/1
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 10 Feb 2015 17:10:30 +0000 (18:10 +0100)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Tue, 24 Feb 2015 16:44:07 +0000 (17:44 +0100)
[Issue#] N/A
[Feature/Bug] N/A
[Problem] dlopen() fails with client library
[Cause] The order of global variables construction in common library is unpredictable.
[Solution] Global variable made member. Strings replaced by const char* const.

[Verification] Use ckm_so_loader 2 100 /usr/lib/libkey-manager-client.so ckmc_save_key

Change-Id: I0add0c1fe3c66ac9d42a94b7e59bf21cadecdefc

src/manager/dpl/log/include/dpl/log/log.h
src/manager/dpl/log/src/log.cpp

index 43064a5..28e1eb4 100644 (file)
@@ -26,6 +26,8 @@
 #include <dpl/log/abstract_log_provider.h>
 #include <sstream>
 #include <list>
+#include <unordered_map>
+#include <string>
 
 #include <noncopyable.h>
 #include <symbol-visibility.h>
@@ -87,6 +89,13 @@ class COMMON_API LogSystem
     typedef std::list<AbstractLogProvider *> AbstractLogProviderPtrList;
     AbstractLogProviderPtrList m_providers;
     AbstractLogProvider::LogLevel m_level;
+
+    typedef AbstractLogProvider*(*ProviderFn)();
+    /*
+     * It cannot be global as it is used in library constructor and we can't be sure which
+     * constructor is called first: library's or new_provider's.
+     */
+    std::unordered_map<std::string, ProviderFn> m_providerCtor;
 };
 
 /*
index d4571e6..7e61769 100644 (file)
@@ -22,9 +22,8 @@
 #include <stddef.h>
 #include <string.h>
 
-#include <string>
 #include <stdexcept>
-#include <unordered_map>
+
 #include <cassert>
 
 #include <dpl/log/log.h>
@@ -50,30 +49,26 @@ namespace // anonymous
 const char * const CKM_LOG_LEVEL =      "CKM_LOG_LEVEL";
 const char * const CKM_LOG_PROVIDER =   "CKM_LOG_PROVIDER";
 
-const std::string CONSOLE =     "CONSOLE";
-const std::string DLOG =        "DLOG";
-const std::string JOURNALD =    "JOURNALD";
+const char * const CONSOLE =  "CONSOLE";
+const char * const DLOG =     "DLOG";
+const char * const JOURNALD = "JOURNALD";
+} // namespace anonymous
 
-typedef AbstractLogProvider*(*provider_fn)();
-std::unordered_map<std::string, provider_fn> new_provider = {
+LogSystem::LogSystem() : m_providerCtor({
 #ifdef BUILD_TYPE_DEBUG
-        { CONSOLE,  []{ return static_cast<AbstractLogProvider*>(new OldStyleLogProvider()); } },
+            { CONSOLE,  []{ return static_cast<AbstractLogProvider*>(new OldStyleLogProvider()); } },
 #endif // BUILD_TYPE_DEBUG
-        { DLOG,     []{ return static_cast<AbstractLogProvider*>(new DLOGLogProvider()); } },
-        { JOURNALD, []{ return static_cast<AbstractLogProvider*>(new JournalLogProvider()); } }
-};
-
-} // namespace anonymous
-
-LogSystem::LogSystem()
+            { DLOG,     []{ return static_cast<AbstractLogProvider*>(new DLOGLogProvider()); } },
+            { JOURNALD, []{ return static_cast<AbstractLogProvider*>(new JournalLogProvider()); } }
+    })
 {
     SetLogLevel(getenv(CKM_LOG_LEVEL));
 
     AbstractLogProvider* prv = NULL;
     try {
-        prv = new_provider.at(getenv(CKM_LOG_PROVIDER))();
+        prv = m_providerCtor.at(getenv(CKM_LOG_PROVIDER))();
     } catch(const std::exception&) {
-        prv = new_provider[DLOG]();
+        prv = m_providerCtor[DLOG]();
     }
     AddProvider(prv);
 }
@@ -102,7 +97,7 @@ void LogSystem::RemoveProvider(AbstractLogProvider *provider)
 void LogSystem::SelectProvider(const std::string& name)
 {
     // let it throw
-    provider_fn& prv = new_provider.at(name);
+    ProviderFn& prv = m_providerCtor.at(name);
 
     RemoveProviders();
     AddProvider(prv());