]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Lazily attach console when logging to stdout.
authorVMware, Inc <>
Tue, 19 Oct 2010 19:19:57 +0000 (12:19 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Tue, 19 Oct 2010 19:19:57 +0000 (12:19 -0700)
Instead of attaching a console when configuring the logger, do it when
the first log message is written. This ensures that a console only pops
up when the application actually tries to use it. The console is also
detached when the last log domain using it is shut down.

This avoids an issue where consoles would pop up when you configured std
logging for a different application, but all applications sharing the tools
config file ended up attaching a console to their process.

Also fix an issue where an invalid handler was set up for the app's main
log domain, which could cause an ASSERT to be hit.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/libvmtools/stdLogger.c
open-vm-tools/libvmtools/vmtoolsLog.c

index f8d73d220810a6a070acc40fb8d4de0e23e8785d..e1bca6ec47c15c964f0477a23a2a52f0da0d45c9 100644 (file)
 #include "vmtoolsInt.h"
 #include <stdio.h>
 
+#if defined(_WIN32)
+static GStaticMutex gConsoleLock = G_STATIC_MUTEX_INIT;
+static gint gRefCount = 0;
+#endif
+
+typedef struct StdLoggerData {
+   LogHandlerData    handler;
+#if defined(_WIN32)
+   gboolean          attached;
+#endif
+} StdLoggerData;
+
 
 /*
  ******************************************************************************
@@ -36,7 +48,7 @@
  * @param[in] domain    Unused.
  * @param[in] level     Log level.
  * @param[in] message   Message to log.
- * @param[in] _data     Unused.
+ * @param[in] data      Logger data.
  * @param[in] errfn     Unused.
  *
  * @return TRUE.
@@ -48,15 +60,59 @@ static gboolean
 VMStdLoggerLog(const gchar *domain,
                GLogLevelFlags level,
                const gchar *message,
-               LogHandlerData *_data,
+               LogHandlerData *data,
                LogErrorFn errfn)
 {
    FILE *dest = (level < G_LOG_LEVEL_MESSAGE) ? stderr : stdout;
+
+#if defined(_WIN32)
+   StdLoggerData *sdata = (StdLoggerData *) data;
+
+   if (!sdata->attached) {
+      g_static_mutex_lock(&gConsoleLock);
+      if (gRefCount != 0 || VMTools_AttachConsole()) {
+         gRefCount++;
+         sdata->attached = TRUE;
+      }
+      g_static_mutex_unlock(&gConsoleLock);
+   }
+
+   if (!sdata->attached) {
+      return FALSE;
+   }
+#endif
+
    fputs(message, dest);
    return TRUE;
 }
 
 
+/*
+ *******************************************************************************
+ * VMStdLoggerDestroy --                                                  */ /**
+ *
+ * Cleans up the internal state of the logger.
+ *
+ * @param[in] data   Logger data.
+ *
+ *******************************************************************************
+ */
+
+static void
+VMStdLoggerDestroy(LogHandlerData *data)
+{
+#if defined(_WIN32)
+   StdLoggerData *sdata = (StdLoggerData *) data;
+   g_static_mutex_lock(&gConsoleLock);
+   if (sdata->attached && --gRefCount == 0) {
+      FreeConsole();
+   }
+   g_static_mutex_unlock(&gConsoleLock);
+#endif
+   g_free(data);
+}
+
+
 /*
  ******************************************************************************
  * VMStdLoggerConfig --                                                 */ /**
@@ -79,21 +135,13 @@ VMStdLoggerConfig(const gchar *defaultDomain,
                   const gchar *name,
                   GKeyFile *cfg)
 {
-   LogHandlerData *data;
-
-#if defined(_WIN32)
-   if (!VMTools_AttachConsole()) {
-      return NULL;
-   }
-#endif
-
-   data = g_new0(LogHandlerData, 1);
-   data->logfn = VMStdLoggerLog;
-   data->convertToLocal = TRUE;
-   data->timestamp = TRUE;
-   data->shared = FALSE;
-   data->copyfn = NULL;
-   data->dtor = (LogHandlerDestroyFn) g_free;
-   return data;
+   StdLoggerData *data = g_new0(StdLoggerData, 1);
+   data->handler.logfn = VMStdLoggerLog;
+   data->handler.convertToLocal = TRUE;
+   data->handler.timestamp = TRUE;
+   data->handler.shared = FALSE;
+   data->handler.copyfn = NULL;
+   data->handler.dtor = VMStdLoggerDestroy;
+   return &data->handler;
 }
 
index f52d43e23796a2ba6421a7c6ea5623ad7e2ac8e7..1cb9a465f5ea4a662ff866402e8b6b359f0d3d58 100644 (file)
@@ -425,7 +425,12 @@ VMToolsConfigLogDomain(const gchar *domain,
 
       if (configfn == NULL) {
          g_warning("Unknown log handler '%s', using default.", handler);
-         goto exit;
+         if (strcmp(domain, gLogDomain) == 0) {
+            configfn = DEFAULT_HANDLER->configfn;
+            hid = DEFAULT_HANDLER->id;
+         } else {
+            goto exit;
+         }
       }
 
       data = configfn(gLogDomain, domain, handler, cfg);