From c00b251dfebc4551904a1826f1fa6c0d766f394a Mon Sep 17 00:00:00 2001 From: Thai Phan Date: Wed, 18 Mar 2015 22:52:01 +1100 Subject: [PATCH] Spin off PlatformApis thing into separate library --- src/Kestrel.LibraryLoader/Library.cs | 47 +++++++++++++++++++ .../PlatformApis.cs | 28 +++++------ src/Kestrel.LibraryLoader/project.json | 7 +++ .../Networking/Libuv.cs | 21 ++------- .../project.json | 3 +- 5 files changed, 72 insertions(+), 34 deletions(-) create mode 100644 src/Kestrel.LibraryLoader/Library.cs rename src/{Microsoft.AspNet.Server.Kestrel/Networking => Kestrel.LibraryLoader}/PlatformApis.cs (81%) create mode 100644 src/Kestrel.LibraryLoader/project.json diff --git a/src/Kestrel.LibraryLoader/Library.cs b/src/Kestrel.LibraryLoader/Library.cs new file mode 100644 index 000000000..b3ad13079 --- /dev/null +++ b/src/Kestrel.LibraryLoader/Library.cs @@ -0,0 +1,47 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace Kestrel.LibraryLoader +{ + public abstract class Library + { + public Library() + { + IsWindows = PlatformApis.IsWindows(); + if (!IsWindows) + { + IsDarwin = PlatformApis.IsDarwin(); + } + } + + public bool IsWindows; + public bool IsDarwin; + + public Func LoadLibrary; + public Func FreeLibrary; + public Func GetProcAddress; + + public virtual void Load(string dllToLoad) + { + PlatformApis.Apply(this); + + var module = LoadLibrary(dllToLoad); + if (module == IntPtr.Zero) + { + throw new InvalidOperationException("Unable to load library."); + } + + foreach (var field in GetType().GetTypeInfo().DeclaredFields) + { + var procAddress = GetProcAddress(module, field.Name.TrimStart('_')); + if (procAddress == IntPtr.Zero) + { + continue; + } + var value = Marshal.GetDelegateForFunctionPointer(procAddress, field.FieldType); + field.SetValue(this, value); + } + } + } +} diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/PlatformApis.cs b/src/Kestrel.LibraryLoader/PlatformApis.cs similarity index 81% rename from src/Microsoft.AspNet.Server.Kestrel/Networking/PlatformApis.cs rename to src/Kestrel.LibraryLoader/PlatformApis.cs index 55a2fe77b..f525bd919 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/PlatformApis.cs +++ b/src/Kestrel.LibraryLoader/PlatformApis.cs @@ -2,11 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Reflection; using System.Runtime.InteropServices; -using System.Text; -namespace Microsoft.AspNet.Server.Kestrel.Networking +namespace Kestrel.LibraryLoader { public static class PlatformApis { @@ -48,15 +46,15 @@ public static bool IsDarwin() return string.Equals(GetUname(), "Darwin", StringComparison.Ordinal); } - public static void Apply(Libuv libuv) + public static void Apply(Library library) { - if (libuv.IsWindows) + if (library.IsWindows) { - WindowsApis.Apply(libuv); + WindowsApis.Apply(library); } else { - LinuxApis.Apply(libuv); + LinuxApis.Apply(library); } } @@ -71,11 +69,11 @@ public static class WindowsApis [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); - public static void Apply(Libuv libuv) + public static void Apply(Library library) { - libuv.LoadLibrary = LoadLibrary; - libuv.FreeLibrary = FreeLibrary; - libuv.GetProcAddress = GetProcAddress; + library.LoadLibrary = LoadLibrary; + library.FreeLibrary = FreeLibrary; + library.GetProcAddress = GetProcAddress; } } @@ -111,11 +109,11 @@ public static IntPtr GetProcAddress(IntPtr hModule, string procedureName) return errPtr == IntPtr.Zero ? res : IntPtr.Zero; } - public static void Apply(Libuv libuv) + public static void Apply(Library library) { - libuv.LoadLibrary = LoadLibrary; - libuv.FreeLibrary = FreeLibrary; - libuv.GetProcAddress = GetProcAddress; + library.LoadLibrary = LoadLibrary; + library.FreeLibrary = FreeLibrary; + library.GetProcAddress = GetProcAddress; } } } diff --git a/src/Kestrel.LibraryLoader/project.json b/src/Kestrel.LibraryLoader/project.json new file mode 100644 index 000000000..ada86ebeb --- /dev/null +++ b/src/Kestrel.LibraryLoader/project.json @@ -0,0 +1,7 @@ +{ + "version": "1.0.0-*", + "description": "Load libraries between Windows and Unix with delight.", + "compilationOptions": { + "allowUnsafe": true + } +} diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs index 977fb1826..8e0878571 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs @@ -5,28 +5,13 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Text; +using Kestrel.LibraryLoader; namespace Microsoft.AspNet.Server.Kestrel.Networking { - public class Libuv + public class Libuv : Library { - public Libuv() - { - IsWindows = PlatformApis.IsWindows(); - if (!IsWindows) - { - IsDarwin = PlatformApis.IsDarwin(); - } - } - - public bool IsWindows; - public bool IsDarwin; - - public Func LoadLibrary; - public Func FreeLibrary; - public Func GetProcAddress; - - public void Load(string dllToLoad) + public override void Load(string dllToLoad) { PlatformApis.Apply(this); diff --git a/src/Microsoft.AspNet.Server.Kestrel/project.json b/src/Microsoft.AspNet.Server.Kestrel/project.json index 73bb02015..fa7222ce1 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/project.json +++ b/src/Microsoft.AspNet.Server.Kestrel/project.json @@ -2,7 +2,8 @@ "version": "1.0.0-*", "description": "ASP.NET 5 cross platform development web server.", "dependencies": { - "Microsoft.Framework.Runtime.Interfaces": "1.0.0-*" + "Microsoft.Framework.Runtime.Interfaces": "1.0.0-*", + "Kestrel.LibraryLoader": "1.0.0-*" }, "frameworks": { "dnx451": { },