Move creating hostpolicy context and coreclr out of run functions (dotnet/core-setup...
authorElinor Fung <47805090+elinor-fung@users.noreply.github.com>
Sat, 13 Apr 2019 23:07:21 +0000 (16:07 -0700)
committerGitHub <noreply@github.com>
Sat, 13 Apr 2019 23:07:21 +0000 (16:07 -0700)
Commit migrated from https://github.com/dotnet/core-setup/commit/8e0590b0f1320ea455d125c2d75dc230109d8e43

src/installer/corehost/cli/fxr/fx_muxer.cpp
src/installer/corehost/cli/host_startup_info.cpp
src/installer/corehost/cli/host_startup_info.h
src/installer/corehost/cli/hostpolicy/hostpolicy.cpp

index 83faafb..01e63d0 100644 (file)
@@ -760,7 +760,7 @@ int fx_muxer_t::load_runtime_and_get_delegate(
     coreclr_delegate_type delegate_type,
     void** delegate)
 {
-    assert(host_info.is_valid());
+    assert(host_info.is_valid(mode));
 
     pal::string_t runtime_config = _X("");
     pal::string_t impl_dir;
index fbdbbb4..2e9bb13 100644 (file)
@@ -52,12 +52,17 @@ int host_startup_info_t::parse(
     return 0;
 }
 
-const bool host_startup_info_t::is_valid() const
+const bool host_startup_info_t::is_valid(host_mode_t mode) const
 {
-    return (
-        !host_path.empty() &&
-        !dotnet_root.empty() &&
-        !app_path.empty());
+    if (mode == host_mode_t::libhost)
+    {
+        // libhost allows empty app path
+        return !host_path.empty() && !dotnet_root.empty();
+    }
+
+    return !host_path.empty()
+        && !dotnet_root.empty()
+        && !app_path.empty();
 }
 
 const pal::string_t host_startup_info_t::get_app_name() const
index 1f09896..3530171 100644 (file)
@@ -6,6 +6,7 @@
 #define __HOST_STARTUP_INFO_H_
 
 #include "pal.h"
+#include "host_interface.h"
 
 struct host_startup_info_t
 {
@@ -19,7 +20,7 @@ struct host_startup_info_t
         int argc,
         const pal::char_t* argv[]);
 
-    const bool is_valid() const;
+    const bool is_valid(host_mode_t mode) const;
 
     const pal::string_t get_app_name() const;
 
index bf35280..5aa0d7e 100644 (file)
@@ -27,7 +27,7 @@ namespace
     std::mutex g_lib_lock;
     std::weak_ptr<coreclr_t> g_lib_coreclr;
 
-    int create_coreclr(const hostpolicy_context_t &context, const char* app_domain_friendly_name, std::unique_ptr<coreclr_t> &coreclr)
+    int create_coreclr(const hostpolicy_context_t &context, host_mode_t mode, std::unique_ptr<coreclr_t> &coreclr)
     {
         // Verbose logging
         if (trace::is_enabled())
@@ -38,6 +38,8 @@ namespace
         std::vector<char> host_path;
         pal::pal_clrstring(context.host_path, &host_path);
 
+        const char *app_domain_friendly_name = mode == host_mode_t::libhost ? "clr_libhost" : "clrhost";
+
         // Create a CoreCLR instance
         trace::verbose(_X("CoreCLR path = '%s', CoreCLR dir = '%s'"), context.clr_path.c_str(), context.clr_dir.c_str());
         auto hr = coreclr_t::create(
@@ -55,11 +57,29 @@ namespace
 
         return StatusCode::Success;
     }
+
+    int create_hostpolicy_context(
+        hostpolicy_init_t &hostpolicy_init,
+        const arguments_t &args,
+        bool breadcrumbs_enabled,
+        std::shared_ptr<hostpolicy_context_t> &context)
+    {
+
+        std::unique_ptr<hostpolicy_context_t> context_local(new hostpolicy_context_t());
+        int rc = context_local->initialize(hostpolicy_init, args, breadcrumbs_enabled);
+        if (rc != StatusCode::Success)
+            return rc;
+
+        context = std::move(context_local);
+
+        return StatusCode::Success;
+    }
 }
 
-int run_as_lib(
+int get_or_create_coreclr(
     hostpolicy_init_t &hostpolicy_init,
     const arguments_t &args,
+    host_mode_t mode,
     std::shared_ptr<coreclr_t> &coreclr)
 {
     coreclr = g_lib_coreclr.lock();
@@ -86,7 +106,7 @@ int run_as_lib(
             return rc;
 
         std::unique_ptr<coreclr_t> coreclr_local;
-        rc = create_coreclr(context, "clr_libhost", coreclr_local);
+        rc = create_coreclr(context, mode, coreclr_local);
         if (rc != StatusCode::Success)
             return rc;
 
@@ -132,48 +152,32 @@ int run_host_command(
 }
 
 int run_as_app(
-    hostpolicy_init_t &hostpolicy_init,
-    const arguments_t &args)
+    const std::shared_ptr<coreclr_t> &coreclr,
+    const hostpolicy_context_t &context,
+    int argc,
+    const pal::char_t **argv)
 {
-    hostpolicy_context_t context {};
-    int rc = context.initialize(g_init, args, true /* enable_breadcrumbs */);
-    if (rc != StatusCode::Success)
-        return rc;
-
-    std::unique_ptr<coreclr_t> coreclr;
-    rc = create_coreclr(context, "clrhost", coreclr);
-    if (rc != StatusCode::Success)
-        return rc;
-
-    assert(g_coreclr == nullptr);
-    g_coreclr = std::move(coreclr);
-
-    {
-        std::lock_guard<std::mutex> lock{ g_lib_lock };
-        g_lib_coreclr = g_coreclr;
-    }
-
     // Initialize clr strings for arguments
-    std::vector<std::vector<char>> argv_strs(args.app_argc);
-    std::vector<const char*> argv(args.app_argc);
-    for (int i = 0; i < args.app_argc; i++)
+    std::vector<std::vector<char>> argv_strs(argc);
+    std::vector<const char*> argv_local(argc);
+    for (int i = 0; i < argc; i++)
     {
-        pal::pal_clrstring(args.app_argv[i], &argv_strs[i]);
-        argv[i] = argv_strs[i].data();
+        pal::pal_clrstring(argv[i], &argv_strs[i]);
+        argv_local[i] = argv_strs[i].data();
     }
 
     if (trace::is_enabled())
     {
         pal::string_t arg_str;
-        for (int i = 0; i < argv.size(); i++)
+        for (int i = 0; i < argv_local.size(); i++)
         {
             pal::string_t cur;
-            pal::clr_palstring(argv[i], &cur);
+            pal::clr_palstring(argv_local[i], &cur);
             arg_str.append(cur);
             arg_str.append(_X(","));
         }
         trace::info(_X("Launch host: %s, app: %s, argc: %d, args: %s"), context.host_path.c_str(),
-            context.application.c_str(), args.app_argc, arg_str.c_str());
+            context.application.c_str(), argc, arg_str.c_str());
     }
 
     std::vector<char> managed_app;
@@ -189,8 +193,8 @@ int run_as_app(
     // Execute the application
     unsigned int exit_code;
     auto hr = g_coreclr->execute_assembly(
-        argv.size(),
-        argv.data(),
+        argv_local.size(),
+        argv_local.data(),
         managed_app.data(),
         &exit_code);
 
@@ -300,7 +304,7 @@ int corehost_main_init(
     arguments_t& args)
 {
     // Take care of arguments
-    if (!hostpolicy_init.host_info.is_valid())
+    if (!hostpolicy_init.host_info.is_valid(hostpolicy_init.host_mode))
     {
         // For backwards compat (older hostfxr), default the host_info
         hostpolicy_init.host_info.parse(argc, argv);
@@ -316,7 +320,26 @@ SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
     if (rc != StatusCode::Success)
         return rc;
 
-    return run_as_app(g_init, args);
+    std::shared_ptr<hostpolicy_context_t> context;
+    rc = create_hostpolicy_context(g_init, args, true /* breadcrumbs_enabled */, context);
+    if (rc != StatusCode::Success)
+        return rc;
+
+    std::unique_ptr<coreclr_t> coreclr;
+    rc = create_coreclr(*context, g_init.host_mode, coreclr);
+    if (rc != StatusCode::Success)
+        return rc;
+
+    assert(g_coreclr == nullptr);
+    g_coreclr = std::move(coreclr);
+
+    {
+        std::lock_guard<std::mutex> lock{ g_lib_lock };
+        g_lib_coreclr = g_coreclr;
+    }
+
+    rc = run_as_app(g_coreclr, *context, args.app_argc, args.app_argv);
+    return rc;
 }
 
 SHARED_API int corehost_main_with_output_buffer(const int argc, const pal::char_t* argv[], pal::char_t buffer[], int32_t buffer_size, int32_t* required_buffer_size)
@@ -362,11 +385,41 @@ SHARED_API int corehost_main_with_output_buffer(const int argc, const pal::char_
 int corehost_libhost_init(hostpolicy_init_t &hostpolicy_init, const pal::string_t& location, arguments_t& args)
 {
     // Host info should always be valid in the delegate scenario
-    assert(hostpolicy_init.host_info.is_valid());
+    assert(hostpolicy_init.host_info.is_valid(host_mode_t::libhost));
 
     return corehost_init(hostpolicy_init, 0, nullptr, location, args);
 }
 
+namespace
+{
+    int get_coreclr_delegate(const std::shared_ptr<coreclr_t> &coreclr, coreclr_delegate_type type, void** delegate)
+    {
+        switch (type)
+        {
+        case coreclr_delegate_type::com_activation:
+            return coreclr->create_delegate(
+                "System.Private.CoreLib",
+                "Internal.Runtime.InteropServices.ComActivator",
+                "GetClassFactoryForTypeInternal",
+                delegate);
+        case coreclr_delegate_type::load_in_memory_assembly:
+            return coreclr->create_delegate(
+                "System.Private.CoreLib",
+                "Internal.Runtime.InteropServices.InMemoryAssemblyLoader",
+                "LoadInMemoryAssembly",
+                delegate);
+        case coreclr_delegate_type::winrt_activation:
+            return coreclr->create_delegate(
+                "System.Private.CoreLib",
+                "Internal.Runtime.InteropServices.WindowsRuntime.ActivationFactoryLoader",
+                "GetActivationFactory",
+                delegate);
+        default:
+            return StatusCode::LibHostInvalidArgs;
+        }
+    }
+}
+
 SHARED_API int corehost_get_coreclr_delegate(coreclr_delegate_type type, void** delegate)
 {
     arguments_t args;
@@ -376,34 +429,11 @@ SHARED_API int corehost_get_coreclr_delegate(coreclr_delegate_type type, void**
         return rc;
 
     std::shared_ptr<coreclr_t> coreclr;
-    rc = run_as_lib(g_init, args, coreclr);
+    rc = get_or_create_coreclr(g_init, args, g_init.host_mode, coreclr);
     if (rc != StatusCode::Success)
         return rc;
 
-    switch (type)
-    {
-    case coreclr_delegate_type::com_activation:
-        return coreclr->create_delegate(
-            "System.Private.CoreLib",
-            "Internal.Runtime.InteropServices.ComActivator",
-            "GetClassFactoryForTypeInternal",
-            delegate);
-    case coreclr_delegate_type::load_in_memory_assembly:
-        return coreclr->create_delegate(
-            "System.Private.CoreLib",
-            "Internal.Runtime.InteropServices.InMemoryAssemblyLoader",
-            "LoadInMemoryAssembly",
-            delegate);
-    case coreclr_delegate_type::winrt_activation:
-        return coreclr->create_delegate(
-            "System.Private.CoreLib",
-            "Internal.Runtime.InteropServices.WindowsRuntime.ActivationFactoryLoader",
-            "GetActivationFactory",
-            delegate
-        );
-    default:
-        return StatusCode::LibHostInvalidArgs;
-    }
+    return get_coreclr_delegate(coreclr, type, delegate);
 }
 
 SHARED_API int corehost_unload()
@@ -441,7 +471,7 @@ SHARED_API int corehost_resolve_component_dependencies(
     // The assumption is that component dependency resolution will only be called
     // when the coreclr is hosted through this hostpolicy and thus it will
     // have already called corehost_main_init.
-    if (!g_init.host_info.is_valid())
+    if (!g_init.host_info.is_valid(g_init.host_mode))
     {
         trace::error(_X("Hostpolicy must be initialized and corehost_main must have been called before calling corehost_resolve_component_dependencies."));
         return StatusCode::CoreHostLibLoadFailure;