From f09607b429281fa4ddd25cc1c5ba6b97ad9040b6 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Tue, 31 Mar 2020 12:38:39 +0900 Subject: [PATCH] Set environment (LANG, LC_MESSAGE, LC_ALL) before using ICU API. In order to operate ICU (used for globalization) normally, "LANG" and "LC_ALL" environment variables must be set before using ICU API. In case of application running, AppFW set that variable. But when preloading the dll in the candidate process, those environment variables are not set. As a result, CultureInfo is incorrectly generated and malfunctions. For example, uloc_getDefault() returns en_US_POSIX, CultureInfo is set to invariant mode. Additionally, to apply language setting from native to managed, terminate and recreate candidate process when system language setting is changed. After applying this patches, launching performance is reduced by 15ms ~ 20ms. That is because previous .net application is launched in invariant mode. (In invariant mode, string-related operations are fast.) --- NativeLauncher/launcher/dotnet/dotnet_launcher.cc | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/NativeLauncher/launcher/dotnet/dotnet_launcher.cc b/NativeLauncher/launcher/dotnet/dotnet_launcher.cc index 890e5b7..650d5b7 100644 --- a/NativeLauncher/launcher/dotnet/dotnet_launcher.cc +++ b/NativeLauncher/launcher/dotnet/dotnet_launcher.cc @@ -245,6 +245,35 @@ static void initEnvForSpecialFolder() } } +// terminate candidate process when language changed +// icu related data (CultureInfo, etc) should be recreated. +static void langChangedCB(keynode_t *key, void* data) +{ + _INFO("terminiate candidate process to update language."); + exit(0); +} + +static void setLang() +{ + char* lang = vconf_get_str(VCONFKEY_LANGSET); + if (!lang) { + _ERR("Fail to get language from vconf"); + return; + } + + // In order to operate ICU (used for globalization) normally, the following + // environment variables must be set before using ICU API. + // When running Applicaiton, the following environment variables are set by AppFW. + // But when preloading the dll in the candidate process, the following environment variables are not set + // As a result, CultureInfo is incorrectly generated and malfunctions. + // For example, uloc_getDefault() returns en_US_POSIX, CultureInfo is set to invariant mode. + setenv("LANG", const_cast(lang), 1); + setenv("LC_MESSAGES", const_cast(lang), 1); + setenv("LC_ALL", const_cast(lang), 1); + + free(lang); +} + void CoreRuntime::preloadTypes() { const static std::string initDllPath = concatPath(__FRAMEWORK_DIR, "Tizen.Init.dll"); @@ -288,6 +317,9 @@ CoreRuntime::CoreRuntime(const char* mode) : // Intiailize ecore first (signal handlers, etc.) before runtime init. ecore_init(); + // set language environment to support ICU + setLang(); + char *env = nullptr; env = getenv("CORECLR_ENABLE_PROFILING"); if (env != nullptr && !strcmp(env, "1")) { @@ -407,6 +439,10 @@ int CoreRuntime::initialize(bool standalone, bool useDlog, const char* corerunRo if (!standalone) { pluginPreload(); + + // terminate candidate process if language is changed. + // CurrentCulture created for preloaded dlls should be updated. + vconf_notify_key_changed(VCONFKEY_LANGSET, langChangedCB, NULL); } // Set environment for System.Environment.SpecialFolder @@ -586,6 +622,8 @@ int CoreRuntime::launch(const char* appId, const char* root, const char* path, i free(localDataPath); } + vconf_ignore_key_changed(VCONFKEY_LANGSET, langChangedCB); + pluginBeforeExecute(); _INFO("execute assembly : %s", path); -- 2.7.4