X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=NativeLauncher%2Fhydra%2Fhydra_main.cc;h=7ced0a3f91cfb817e405fa239cb7bc8f709f9beb;hb=04a885649ac58636a6b7da2c20449adceb84e40b;hp=29667453fd07243cbc089c66357eac93b40f1d01;hpb=2b3dafe36d2b78a5afa3b80d05ff5a6db17e0260;p=platform%2Fcore%2Fdotnet%2Flauncher.git diff --git a/NativeLauncher/hydra/hydra_main.cc b/NativeLauncher/hydra/hydra_main.cc index 2966745..7ced0a3 100644 --- a/NativeLauncher/hydra/hydra_main.cc +++ b/NativeLauncher/hydra/hydra_main.cc @@ -22,26 +22,78 @@ #include #include #include +#include + +#include +#include +#include #include "log.h" #include "launcher_env.h" -const char* __coreclr_lib = "/usr/share/dotnet.tizen/netcoreapp/libcoreclr.so"; -const char* __dotnet_launcher = "/usr/bin/dotnet-launcher"; +static const char* __coreclr_lib = "/usr/share/dotnet.tizen/netcoreapp/libcoreclr.so"; +static const char* __dotnet_loader = "/usr/bin/dotnet-loader"; typedef int (*coreclr_preload_assembly_ptr)(const char* assemblyPath); -typedef int (*launcher_real_main_ptr)(int argc, char *argv[], const char* mode); +typedef int (*launcher_real_main_ptr)(int argc, char *argv[]); -static std::string absolutePath(const std::string& path) +static std::string getAbsolutePath(const std::string& path) { std::string absPath; - char realPath[PATH_MAX]; - if (realpath(path.c_str(), realPath) != nullptr && realPath[0] != '\0') + char *realPath = realpath(path.c_str(), NULL); + if (realPath) { absPath.assign(realPath); + free(realPath); + } return absPath; } +static bool isFile(const std::string& path) +{ + struct stat sb; + return lstat(path.c_str(), &sb) == 0; +} + +static std::string replaceAll(const std::string& str, const std::string& pattern, const std::string& replace) +{ + std::string result = str; + std::string::size_type pos = 0; + std::string::size_type offset = 0; + + while ((pos = result.find(pattern, offset)) != std::string::npos) { + result.replace(result.begin() + pos, result.begin() + pos + pattern.size(), replace); + offset = pos + replace.size(); + } + + return result; +} + +static std::string findDllPath(const std::string& filename) +{ + const std::string netcoreappDir = "/usr/share/dotnet.tizen/netcoreapp/"; + const std::string frameworkDir = "/usr/share/dotnet.tizen/framework/"; + + std::string result; + + // check whether the target file exist under netcoreapp directory + result = netcoreappDir + filename; + if (isFile(result)) { + return result; + } + + // check whether the target file exist under framework directory + result = frameworkDir + filename; + if (isFile(result)) { + return result; + } + + // dll file is not found. return empty string + result.clear(); + + return result; +} + static void preloadAssemblies() { #ifdef USE_DEFAULT_BASE_ADDR @@ -61,21 +113,78 @@ static void preloadAssemblies() return; } - std::ifstream preloadList(AOT_PRELOAD_PATH); - if (preloadList) { - std::string path; - while (getline(preloadList, path)) { - int st = preloadAssembly(absolutePath(path).c_str()); - if (st != 0) { - _DBG("preload of %s failed! (0x%08x)", path.c_str(), st); - } else { - _DBG("preload of %s succeded", path.c_str()); - } + const std::string preloadDir = "/usr/share/dotnet.tizen/preload/"; + + // get file list from preload directory + // file is sorted by std::set + std::set preloadFiles; + DIR* dirp = opendir(preloadDir.c_str()); + struct dirent * dp; + while ((dp = readdir(dirp)) != NULL) { + if (dp->d_type != DT_DIR) { + // Make sure that the file name follows naming conventions. + if (dp->d_name && + isdigit(dp->d_name[0]) && + isdigit(dp->d_name[1]) && + (dp->d_name[2] == '.')) { + preloadFiles.insert(preloadDir + dp->d_name); + } } } + closedir(dirp); + + // get dll list from each preload file, and preload dll. + std::set dllList; + std::ifstream ifs; + std::string in_line; + for (const auto& pf: preloadFiles) { + ifs.open(pf); + if (!ifs.is_open()) { + _ERR("failed to open preload file (%s)", pf.c_str()); + continue; + } + + while (std::getline(ifs, in_line)) { + in_line = in_line.substr(0, in_line.find_first_of(" ", 0)); + + // select dll file case + if (in_line[0] == '#' || + in_line[0] == ' ' || + in_line.empty() || + (in_line.find(".dll") == std::string::npos)) { + continue; + } + + // only native image should be passed as a parameter of coreclr_preload_assembly. + if (in_line.find(".ni.dll") == std::string::npos && + in_line.compare("System.Private.CoreLib.dll")) { + in_line = replaceAll(in_line, ".dll", ".ni.dll"); + } + + // coreclr_preload_assembly cannot ignore duplicate loading. + // Therefore, only one dll should be preloaded. + // dllList is used to ignore duplicated loading request + if (dllList.insert(in_line).second) { + // check whether the target file exist under netcoreapp directory + std::string path = findDllPath(in_line); + if (!path.empty()) { + int st = preloadAssembly(getAbsolutePath(path).c_str()); + if (st != 0) { + _ERR("preload of %s failed! (0x%08x)", path.c_str(), st); + } else { + _INFO("preload of %s succeeded", path.c_str()); + } + } else { + _ERR("preload failed : file (%s) does not eixst", in_line.c_str()); + } + } + } + + ifs.close(); + } } -int main(int argc, char** argv) +int main(int argc, char** argv) { hydra_lifecycle_callback_s hydra_callback; @@ -87,10 +196,10 @@ int main(int argc, char** argv) hydra_callback.create = [](void* user_data) { _INFO("hydra : create"); }; - + hydra_callback.fork = [](int argc, char **argv, void* user_data) -> int { _INFO("hydra : fork"); - void* launcher_h = dlopen(__dotnet_launcher, RTLD_NOW | RTLD_GLOBAL); + void* launcher_h = dlopen(__dotnet_loader, RTLD_NOW | RTLD_GLOBAL); if (launcher_h == nullptr) { _DBG("dlopen failed to open dotnet-launcher"); return -1; @@ -99,10 +208,11 @@ int main(int argc, char** argv) launcher_real_main_ptr realMain = (launcher_real_main_ptr)dlsym(launcher_h, "realMain"); if (realMain == nullptr) { _DBG("realMain is not found in the dotnet-launcher"); + dlclose(launcher_h); return -1; } - return realMain(argc, argv, "default"); + return realMain(argc, argv); }; hydra_callback.terminate = [](void* user_data)-> int { @@ -112,4 +222,3 @@ int main(int argc, char** argv) return launchpad_hydra_main(argc, argv, &hydra_callback, nullptr); } -