From: VMware, Inc <> Date: Tue, 19 Oct 2010 19:19:57 +0000 (-0700) Subject: Lazily attach console when logging to stdout. X-Git-Tag: 2010.10.18-313025~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c57e56b06d5fa2b5455a55ff062d3f776a4f9a3d;p=thirdparty%2Fopen-vm-tools.git Lazily attach console when logging to stdout. 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 --- diff --git a/open-vm-tools/libvmtools/stdLogger.c b/open-vm-tools/libvmtools/stdLogger.c index f8d73d220..e1bca6ec4 100644 --- a/open-vm-tools/libvmtools/stdLogger.c +++ b/open-vm-tools/libvmtools/stdLogger.c @@ -26,6 +26,18 @@ #include "vmtoolsInt.h" #include +#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; } diff --git a/open-vm-tools/libvmtools/vmtoolsLog.c b/open-vm-tools/libvmtools/vmtoolsLog.c index f52d43e23..1cb9a465f 100644 --- a/open-vm-tools/libvmtools/vmtoolsLog.c +++ b/open-vm-tools/libvmtools/vmtoolsLog.c @@ -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);