Skip to content

Commit

Permalink
Handle self-contained application load (#2036)
Browse files Browse the repository at this point in the history
* Updates to handle self-contained application load.

* Removing stopwatch instrumentation.
  • Loading branch information
kshyju committed Nov 8, 2023
1 parent e853ae5 commit 6b2e257
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 30 deletions.
60 changes: 34 additions & 26 deletions host/src/FunctionsNetHost/AppLoader/AppLoader.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Diagnostics;
using System.Runtime.InteropServices;

namespace FunctionsNetHost
{
// If having problems with the managed host, enable the following:
// Environment.SetEnvironmentVariable("COREHOST_TRACE", "1");
// In Unix environment, you need to run the below command in the terminal to set the environment variable.
// export COREHOST_TRACE=1

/// <summary>
/// Manages loading hostfxr & worker assembly.
/// </summary>
Expand All @@ -14,43 +20,36 @@ internal sealed class AppLoader : IDisposable
private IntPtr _hostContextHandle = IntPtr.Zero;
private bool _disposed;

internal AppLoader()
internal int RunApplication(string? assemblyPath)
{
LoadHostfxrLibrary();
}
ArgumentNullException.ThrowIfNull(assemblyPath, nameof(assemblyPath));

private void LoadHostfxrLibrary()
{
// If having problems with the managed host, enable the following:
// Environment.SetEnvironmentVariable("COREHOST_TRACE", "1");
// In Unix environment, you need to run the below command in the terminal to set the environment variable.
// export COREHOST_TRACE=1
unsafe
{
var parameters = new NetHost.get_hostfxr_parameters
{
size = sizeof(NetHost.get_hostfxr_parameters),
assembly_path = GetCharArrayPointer(assemblyPath)
};

var hostfxrFullPath = NetHost.GetHostFxrPath();
Logger.LogTrace($"hostfxr path:{hostfxrFullPath}");
var hostfxrFullPath = NetHost.GetHostFxrPath(&parameters);
Logger.LogTrace($"hostfxr path:{hostfxrFullPath}");

_hostfxrHandle = NativeLibrary.Load(hostfxrFullPath);
if (_hostfxrHandle == IntPtr.Zero)
{
Logger.Log($"Failed to load hostfxr. hostfxr path:{hostfxrFullPath}");
return;
}
_hostfxrHandle = NativeLibrary.Load(hostfxrFullPath);

Logger.LogTrace($"hostfxr library loaded successfully.");
}
if (_hostfxrHandle == IntPtr.Zero)
{
Logger.Log($"Failed to load hostfxr. hostfxrFullPath:{hostfxrFullPath}");
return -1;
}

internal int RunApplication(string? assemblyPath)
{
ArgumentNullException.ThrowIfNull(assemblyPath, nameof(assemblyPath));
Logger.LogTrace($"hostfxr loaded.");

unsafe
{
var error = HostFxr.Initialize(1, new[] { assemblyPath }, IntPtr.Zero, out _hostContextHandle);

if (_hostContextHandle == IntPtr.Zero)
{
Logger.Log(
$"Failed to initialize the .NET Core runtime. Assembly path:{assemblyPath}");
Logger.Log($"Failed to initialize the .NET Core runtime. Assembly path:{assemblyPath}");
return -1;
}

Expand Down Expand Up @@ -98,5 +97,14 @@ private void Dispose(bool disposing)
_disposed = true;
}
}

private static unsafe char* GetCharArrayPointer(string assemblyPath)
{
#if OS_LINUX
return (char*)Marshal.StringToHGlobalAnsi(assemblyPath).ToPointer();
#else
return (char*)Marshal.StringToHGlobalUni(assemblyPath).ToPointer();
#endif
}
}
}
18 changes: 14 additions & 4 deletions host/src/FunctionsNetHost/AppLoader/NetHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,28 @@ namespace FunctionsNetHost
{
internal class NetHost
{
public unsafe struct get_hostfxr_parameters
{
public nint size;

// Optional.Path to the application assembly,
// If specified, hostfxr is located from this directory if present (For self-contained deployments)
public char* assembly_path;
public char* dotnet_root;
}

[DllImport("nethost", CharSet = CharSet.Auto)]
private static extern int get_hostfxr_path(
private unsafe static extern int get_hostfxr_path(
[Out] char[] buffer,
[In] ref int buffer_size,
IntPtr reserved);
get_hostfxr_parameters* parameters);

internal static string GetHostFxrPath()
internal unsafe static string GetHostFxrPath(get_hostfxr_parameters* parameters)
{
char[] buffer = new char[200];
int bufferSize = buffer.Length;

int rc = get_hostfxr_path(buffer, ref bufferSize, IntPtr.Zero);
int rc = get_hostfxr_path(buffer, ref bufferSize, parameters);

if (rc != 0)
{
Expand Down

0 comments on commit 6b2e257

Please sign in to comment.