Fix #4524: Initialize with cleanup handler
authorArmin Novak <armin.novak@thincast.com>
Tue, 3 Apr 2018 07:59:42 +0000 (09:59 +0200)
committerArmin Novak <armin.novak@thincast.com>
Tue, 3 Apr 2018 08:18:59 +0000 (10:18 +0200)
Use singleton initializer and register cleanup handler for logger.

winpr/libwinpr/utils/wlog/wlog.c

index ea233d4..22e79d9 100644 (file)
@@ -28,6 +28,7 @@
 #include <winpr/print.h>
 #include <winpr/debug.h>
 #include <winpr/environment.h>
+#include <winpr/wlog.h>
 
 #if defined(ANDROID)
 #include <android/log.h>
@@ -36,7 +37,6 @@
 
 #include "wlog.h"
 
-
 struct _wLogFilter
 {
        DWORD Level;
@@ -66,12 +66,99 @@ LPCSTR WLOG_LEVELS[7] =
        "OFF"
 };
 
+static INIT_ONCE _WLogInitialized = INIT_ONCE_STATIC_INIT;
 static DWORD g_FilterCount = 0;
 static wLogFilter* g_Filters = NULL;
+static wLog* g_RootLog = NULL;
 
+static wLog* WLog_New(LPCSTR name, wLog* rootLogger);
+static void WLog_Free(wLog* log);
 static LONG WLog_GetFilterLogLevel(wLog* log);
 static int WLog_ParseLogLevel(LPCSTR level);
 static BOOL WLog_ParseFilter(wLogFilter* filter, LPCSTR name);
+static BOOL WLog_ParseFilters(void);
+
+static void WLog_Uninit_(void)
+{
+       DWORD index;
+       wLog* child = NULL;
+       wLog* root = g_RootLog;
+
+       if (!root)
+               return;
+
+       for (index = 0; index < root->ChildrenCount; index++)
+       {
+               child = root->Children[index];
+               WLog_Free(child);
+       }
+
+       WLog_Free(root);
+       g_RootLog = NULL;
+}
+
+static BOOL CALLBACK WLog_InitializeRoot(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
+{
+       char* env;
+       DWORD nSize;
+       DWORD logAppenderType;
+       LPCSTR appender = "WLOG_APPENDER";
+
+       if (!(g_RootLog = WLog_New("", NULL)))
+               return FALSE;
+
+       g_RootLog->IsRoot = TRUE;
+       WLog_ParseFilters();
+       logAppenderType = WLOG_APPENDER_CONSOLE;
+       nSize = GetEnvironmentVariableA(appender, NULL, 0);
+
+       if (nSize)
+       {
+               env = (LPSTR) malloc(nSize);
+
+               if (!env)
+                       goto fail;
+
+               if (GetEnvironmentVariableA(appender, env, nSize) != nSize - 1)
+               {
+                       fprintf(stderr, "%s environment variable modified in my back", appender);
+                       free(env);
+                       goto fail;
+               }
+
+               if (_stricmp(env, "CONSOLE") == 0)
+                       logAppenderType = WLOG_APPENDER_CONSOLE;
+               else if (_stricmp(env, "FILE") == 0)
+                       logAppenderType = WLOG_APPENDER_FILE;
+               else if (_stricmp(env, "BINARY") == 0)
+                       logAppenderType = WLOG_APPENDER_BINARY;
+
+#ifdef HAVE_SYSLOG_H
+               else if (_stricmp(env, "SYSLOG") == 0)
+                       logAppenderType = WLOG_APPENDER_SYSLOG;
+
+#endif /* HAVE_SYSLOG_H */
+#ifdef HAVE_JOURNALD_H
+               else if (_stricmp(env, "JOURNALD") == 0)
+                       logAppenderType = WLOG_APPENDER_JOURNALD;
+
+#endif
+               else if (_stricmp(env, "UDP") == 0)
+                       logAppenderType = WLOG_APPENDER_UDP;
+
+               free(env);
+       }
+
+       if (!WLog_SetLogAppenderType(g_RootLog, logAppenderType))
+               goto fail;
+
+       atexit(WLog_Uninit_);
+       return TRUE;
+fail:
+       free(g_RootLog);
+       g_RootLog = NULL;
+       return FALSE;
+}
 
 static BOOL log_recursion(LPCSTR file, LPCSTR fkt, int line)
 {
@@ -121,7 +208,7 @@ static BOOL log_recursion(LPCSTR file, LPCSTR fkt, int line)
        return TRUE;
 }
 
-BOOL WLog_Write(wLog* log, wLogMessage* message)
+static BOOL WLog_Write(wLog* log, wLogMessage* message)
 {
        BOOL status;
        wLogAppender* appender;
@@ -153,7 +240,7 @@ BOOL WLog_Write(wLog* log, wLogMessage* message)
        return status;
 }
 
-BOOL WLog_WriteData(wLog* log, wLogMessage* message)
+static BOOL WLog_WriteData(wLog* log, wLogMessage* message)
 {
        BOOL status;
        wLogAppender* appender;
@@ -185,7 +272,7 @@ BOOL WLog_WriteData(wLog* log, wLogMessage* message)
        return status;
 }
 
-BOOL WLog_WriteImage(wLog* log, wLogMessage* message)
+static BOOL WLog_WriteImage(wLog* log, wLogMessage* message)
 {
        BOOL status;
        wLogAppender* appender;
@@ -217,7 +304,7 @@ BOOL WLog_WriteImage(wLog* log, wLogMessage* message)
        return status;
 }
 
-BOOL WLog_WritePacket(wLog* log, wLogMessage* message)
+static BOOL WLog_WritePacket(wLog* log, wLogMessage* message)
 {
        BOOL status;
        wLogAppender* appender;
@@ -556,6 +643,7 @@ BOOL WLog_ParseFilters(void)
 
        if (GetEnvironmentVariableA(filter, env, nSize) == nSize - 1)
                res = WLog_AddStringLogFilters(env);
+
        free(env);
        return res;
 }
@@ -603,7 +691,7 @@ LONG WLog_GetFilterLogLevel(wLog* log)
        return log->FilterLevel;
 }
 
-BOOL WLog_ParseName(wLog* log, LPCSTR name)
+static BOOL WLog_ParseName(wLog* log, LPCSTR name)
 {
        char* p;
        int count;
@@ -684,7 +772,6 @@ wLog* WLog_New(LPCSTR name, wLog* rootLogger)
        else
        {
                LPCSTR level = "WLOG_LEVEL";
-
                log->Level = WLOG_INFO;
                nSize = GetEnvironmentVariableA(level, NULL, 0);
 
@@ -741,75 +828,15 @@ void WLog_Free(wLog* log)
        }
 }
 
-static wLog* g_RootLog = NULL;
-
 wLog* WLog_GetRoot(void)
 {
-       char* env;
-       DWORD nSize;
-       DWORD logAppenderType;
-
-       if (!g_RootLog)
-       {
-               LPCSTR appender = "WLOG_APPENDER";
-
-               if (!(g_RootLog = WLog_New("", NULL)))
-                       return NULL;
-
-               g_RootLog->IsRoot = TRUE;
-               WLog_ParseFilters();
-               logAppenderType = WLOG_APPENDER_CONSOLE;
-               nSize = GetEnvironmentVariableA(appender, NULL, 0);
-
-               if (nSize)
-               {
-                       env = (LPSTR) malloc(nSize);
-
-                       if (!env)
-                               goto fail;
-
-                       if (GetEnvironmentVariableA(appender, env, nSize) != nSize - 1)
-                       {
-                               fprintf(stderr, "%s environment variable modified in my back", appender);
-                               free(env);
-                               goto fail;
-                       }
-
-                       if (_stricmp(env, "CONSOLE") == 0)
-                               logAppenderType = WLOG_APPENDER_CONSOLE;
-                       else if (_stricmp(env, "FILE") == 0)
-                               logAppenderType = WLOG_APPENDER_FILE;
-                       else if (_stricmp(env, "BINARY") == 0)
-                               logAppenderType = WLOG_APPENDER_BINARY;
-
-#ifdef HAVE_SYSLOG_H
-                       else if (_stricmp(env, "SYSLOG") == 0)
-                               logAppenderType = WLOG_APPENDER_SYSLOG;
-
-#endif /* HAVE_SYSLOG_H */
-#ifdef HAVE_JOURNALD_H
-                       else if (_stricmp(env, "JOURNALD") == 0)
-                               logAppenderType = WLOG_APPENDER_JOURNALD;
-
-#endif
-                       else if (_stricmp(env, "UDP") == 0)
-                               logAppenderType = WLOG_APPENDER_UDP;
-
-                       free(env);
-               }
-
-               if (!WLog_SetLogAppenderType(g_RootLog, logAppenderType))
-                       goto fail;
-       }
+       if (!InitOnceExecuteOnce(&_WLogInitialized, WLog_InitializeRoot, NULL, NULL))
+               return NULL;
 
        return g_RootLog;
-fail:
-       free(g_RootLog);
-       g_RootLog = NULL;
-       return NULL;
 }
 
-BOOL WLog_AddChild(wLog* parent, wLog* child)
+static BOOL WLog_AddChild(wLog* parent, wLog* child)
 {
        if (parent->ChildrenCount >= parent->ChildrenSize)
        {
@@ -848,7 +875,7 @@ BOOL WLog_AddChild(wLog* parent, wLog* child)
        return TRUE;
 }
 
-wLog* WLog_FindChild(LPCSTR name)
+static wLog* WLog_FindChild(LPCSTR name)
 {
        DWORD index;
        wLog* root;
@@ -904,21 +931,6 @@ BOOL WLog_Init(void)
 
 BOOL WLog_Uninit(void)
 {
-       DWORD index;
-       wLog* child = NULL;
-       wLog* root = g_RootLog;
-
-       if (!root)
-               return FALSE;
-
-       for (index = 0; index < root->ChildrenCount; index++)
-       {
-               child = root->Children[index];
-               WLog_Free(child);
-       }
-
-       WLog_Free(root);
-       g_RootLog = NULL;
-
        return TRUE;
 }
+