diff options
author | vnugent <public@vaughnnugent.com> | 2024-03-31 17:00:45 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2024-03-31 17:00:45 -0400 |
commit | 21130c889bd8564b201aa16c8f645abdf85d374a (patch) | |
tree | 57e685f0f7e5c341264eb890112de35206f3d289 /lib/Utils | |
parent | 55859158fbd0bf54473a0baeb486045a025c7c5d (diff) |
Squashed commit of the following:
commit 448a93bb1d18d032087afe2476ffccb98634a54c
Author: vnugent <public@vaughnnugent.com>
Date: Sun Mar 31 16:56:51 2024 -0400
ci: fix third-party dir cleanup
commit 9afed1427472da1ea13079f98dbe27339e55ee7d
Author: vnugent <public@vaughnnugent.com>
Date: Sun Mar 31 16:43:15 2024 -0400
perf: Deprecate unsafememoryhandle span extensions
commit 3ff90da4f02af47ea6d233fdd4445337ebe36452
Author: vnugent <public@vaughnnugent.com>
Date: Sat Mar 30 21:36:18 2024 -0400
refactor: Updates, advanced tracing, http optimizations
commit 8d6b79b5ae309b36f265ba81529bcef8bfcd7414
Merge: 6c1667b 5585915
Author: vnugent <public@vaughnnugent.com>
Date: Sun Mar 24 21:01:31 2024 -0400
Merge branch 'main' into develop
commit 6c1667be23597513537f8190e2f55d65eb9b7c7a
Author: vnugent <public@vaughnnugent.com>
Date: Fri Mar 22 12:01:53 2024 -0400
refactor: Overhauled native library loading and lazy init
commit ebf688f2f974295beabf7b5def7e6f6f150551d0
Author: vnugent <public@vaughnnugent.com>
Date: Wed Mar 20 22:16:17 2024 -0400
refactor: Update compression header files and macros + Ci build
commit 9c7b564911080ccd5cbbb9851a0757b05e1e9047
Author: vnugent <public@vaughnnugent.com>
Date: Tue Mar 19 21:54:49 2024 -0400
refactor: JWK overhaul & add length getter to FileUpload
commit 6d8c3444e09561e5957491b3cc1ae858e0abdd14
Author: vnugent <public@vaughnnugent.com>
Date: Mon Mar 18 16:13:20 2024 -0400
feat: Add FNV1a software checksum and basic correction tests
commit 00d182088cecefc08ca80b1faee9bed3f215f40b
Author: vnugent <public@vaughnnugent.com>
Date: Fri Mar 15 01:05:27 2024 -0400
chore: #6 Use utils filewatcher instead of built-in
commit d513c10d9895c6693519ef1d459c6a5a76929436
Author: vnugent <public@vaughnnugent.com>
Date: Sun Mar 10 21:58:14 2024 -0400
source tree project location updated
Diffstat (limited to 'lib/Utils')
-rw-r--r-- | lib/Utils/src/AdvancedTrace.cs | 52 | ||||
-rw-r--r-- | lib/Utils/src/Async/AsyncAccessSerializer.cs | 43 | ||||
-rw-r--r-- | lib/Utils/src/Async/AsyncQueue.cs | 12 | ||||
-rw-r--r-- | lib/Utils/src/Extensions/MemoryExtensions.cs | 52 | ||||
-rw-r--r-- | lib/Utils/src/Memory/IMemoryHandle.cs | 4 | ||||
-rw-r--r-- | lib/Utils/src/Memory/MemoryHandle.cs | 15 | ||||
-rw-r--r-- | lib/Utils/src/Memory/MemoryUtil.cs | 45 | ||||
-rw-r--r-- | lib/Utils/src/Memory/UnsafeMemoryHandle.cs | 34 | ||||
-rw-r--r-- | lib/Utils/src/Native/SafeLibraryHandle.cs | 11 | ||||
-rw-r--r-- | lib/Utils/src/Resources/CallbackOpenHandle.cs | 44 | ||||
-rw-r--r-- | lib/Utils/src/Resources/ManagedLibrary.cs | 22 | ||||
-rw-r--r-- | lib/Utils/src/VNLib.Utils.csproj | 4 |
12 files changed, 196 insertions, 142 deletions
diff --git a/lib/Utils/src/AdvancedTrace.cs b/lib/Utils/src/AdvancedTrace.cs new file mode 100644 index 0000000..0507089 --- /dev/null +++ b/lib/Utils/src/AdvancedTrace.cs @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2024 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Utils +* File: AdvancedTrace.cs +* +* AdvancedTrace.cs is part of VNLib.Utils which is part of the larger +* VNLib collection of libraries and utilities. +* +* VNLib.Utils is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published +* by the Free Software Foundation, either version 2 of the License, +* or (at your option) any later version. +* +* VNLib.Utils is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/. +*/ + +using System.Diagnostics; + +namespace VNLib.Utils +{ + /// <summary> + /// Provides methods for advanced tracing that are only optionally compiled + /// with the VNLIB_ADVANCED_TRACING symbol defined + /// </summary> + internal static class AdvancedTrace + { + const string AdvancedTraceSymbol = "VNLIB_ADVANCED_TRACING"; + + [Conditional(AdvancedTraceSymbol)] + public static void WriteLine(string? message) => Trace.WriteLine(message); + + [Conditional(AdvancedTraceSymbol)] + public static void WriteLine(string? message, string? category) => Trace.WriteLine(message, category); + + [Conditional(AdvancedTraceSymbol)] + public static void WriteLineIf(bool condition, string? message) => Trace.WriteLineIf(condition, message); + + [Conditional(AdvancedTraceSymbol)] + public static void WriteLineIf(bool condition, string? message, string? category) => Trace.WriteLineIf(condition, message, category); + + [Conditional(AdvancedTraceSymbol)] + public static void WriteLine(object? value) => Trace.WriteLine(value); + } +}
\ No newline at end of file diff --git a/lib/Utils/src/Async/AsyncAccessSerializer.cs b/lib/Utils/src/Async/AsyncAccessSerializer.cs index 76532bc..1beb4dc 100644 --- a/lib/Utils/src/Async/AsyncAccessSerializer.cs +++ b/lib/Utils/src/Async/AsyncAccessSerializer.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Utils @@ -37,42 +37,35 @@ namespace VNLib.Utils.Async /// Creates a base concrete implementation of an <see cref="IAsyncAccessSerializer{TMoniker}"/> /// </summary> /// <typeparam name="TMoniker">The moniker (key) type</typeparam> - public class AsyncAccessSerializer<TMoniker> : IAsyncAccessSerializer<TMoniker>, ICacheHolder where TMoniker : notnull + /// <remarks> + /// Initializes a new <see cref="AsyncAccessSerializer{TMoniker}"/> with the desired + /// caching pool size and initial capacity + /// </remarks> + /// <param name="maxPoolSize">The maxium number of cached wait entry objects</param> + /// <param name="initialCapacity">The initial capacity of the wait table</param> + /// <param name="keyComparer">The moniker key comparer</param> + public class AsyncAccessSerializer<TMoniker>(int maxPoolSize, int initialCapacity, IEqualityComparer<TMoniker>? keyComparer) + : IAsyncAccessSerializer<TMoniker>, ICacheHolder where TMoniker : notnull { /// <summary> /// The mutual exclusion monitor locking object /// </summary> - protected object StoreLock { get; } + protected object StoreLock { get; } = new(); /// <summary> /// A cache pool for <see cref="WaitEntry"/> /// </summary> - protected Stack<WaitEntry> EntryPool { get; } + protected Stack<WaitEntry> EntryPool { get; } = new(maxPoolSize); /// <summary> /// The table containing all active waiters /// </summary> - protected Dictionary<TMoniker, WaitEntry> WaitTable { get; } + protected Dictionary<TMoniker, WaitEntry> WaitTable { get; } = new(initialCapacity, keyComparer); /// <summary> /// The maxium number of elements allowed in the internal entry cache pool /// </summary> - protected int MaxPoolSize { get; } - - /// <summary> - /// Initializes a new <see cref="AsyncAccessSerializer{TMoniker}"/> with the desired - /// caching pool size and initial capacity - /// </summary> - /// <param name="maxPoolSize">The maxium number of cached wait entry objects</param> - /// <param name="initialCapacity">The initial capacity of the wait table</param> - /// <param name="keyComparer">The moniker key comparer</param> - public AsyncAccessSerializer(int maxPoolSize, int initialCapacity, IEqualityComparer<TMoniker>? keyComparer) - { - MaxPoolSize = maxPoolSize; - StoreLock = new(); - EntryPool = new(maxPoolSize); - WaitTable = new(initialCapacity, keyComparer); - } + protected int MaxPoolSize { get; } = maxPoolSize; ///<inheritdoc/> public virtual Task WaitAsync(TMoniker moniker, CancellationToken cancellation = default) @@ -464,11 +457,9 @@ namespace VNLib.Utils.Async * next task in the queue and be awaitable as a task */ - private sealed class TaskNode : Task + private sealed class TaskNode(Action<object?> callback, object item, CancellationToken cancellation) + : Task(callback, item, cancellation) { - public TaskNode(Action<object?> callback, object item, CancellationToken cancellation) : base(callback, item, cancellation) - { } - public TaskNode? Next { get; set; } } @@ -500,7 +491,7 @@ namespace VNLib.Utils.Async /// another waiter is not selected. /// </para> /// </summary> - /// <returns>A value that indicates if the task was transition successfully</returns> + /// <returns>A value that indicates if the task was transitioned successfully</returns> public readonly bool Release() { //return success if no next waiter diff --git a/lib/Utils/src/Async/AsyncQueue.cs b/lib/Utils/src/Async/AsyncQueue.cs index 45f1219..e94d08e 100644 --- a/lib/Utils/src/Async/AsyncQueue.cs +++ b/lib/Utils/src/Async/AsyncQueue.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Utils @@ -93,19 +93,13 @@ namespace VNLib.Utils.Async /// Initalizes a new unbound channel based queue /// </summary> /// <param name="ubOptions">Channel options</param> - public AsyncQueue(UnboundedChannelOptions ubOptions) - { - _channel = Channel.CreateUnbounded<T>(ubOptions); - } + public AsyncQueue(UnboundedChannelOptions ubOptions) => _channel = Channel.CreateUnbounded<T>(ubOptions); /// <summary> /// Initalizes a new bound channel based queue /// </summary> /// <param name="options">Channel options</param> - public AsyncQueue(BoundedChannelOptions options) - { - _channel = Channel.CreateBounded<T>(options); - } + public AsyncQueue(BoundedChannelOptions options) => _channel = Channel.CreateBounded<T>(options); /// <inheritdoc/> public bool TryEnque(T item) => _channel.Writer.TryWrite(item); diff --git a/lib/Utils/src/Extensions/MemoryExtensions.cs b/lib/Utils/src/Extensions/MemoryExtensions.cs index 8f90525..65d90a0 100644 --- a/lib/Utils/src/Extensions/MemoryExtensions.cs +++ b/lib/Utils/src/Extensions/MemoryExtensions.cs @@ -50,6 +50,8 @@ namespace VNLib.Utils.Extensions /// <returns>A new <see cref="OpenResourceHandle{T}"/> encapsulating the rented array</returns> public static UnsafeMemoryHandle<T> UnsafeAlloc<T>(this ArrayPool<T> pool, int size, bool zero = false) where T : unmanaged { + ArgumentNullException.ThrowIfNull(pool); + T[] array = pool.Rent(size); if (zero) @@ -268,7 +270,7 @@ namespace VNLib.Utils.Extensions /// <summary> /// Gets a reference to the element at the specified offset from the base - /// address of the <see cref="MemoryHandle{T}"/> + /// address of the <see cref="IMemoryHandle{T}"/> /// </summary> /// <param name="block"></param> /// <param name="offset">The element offset from the base address to add to the returned reference</param> @@ -766,52 +768,6 @@ namespace VNLib.Utils.Extensions #endregion /// <summary> - /// Slices the current array by the specified starting offset to the end - /// of the array - /// </summary> - /// <typeparam name="T">The array type</typeparam> - /// <param name="arr"></param> - /// <param name="start">The start offset of the new array slice</param> - /// <returns>The sliced array</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static T[] Slice<T>(this T[] arr, int start) - { - ArgumentNullException.ThrowIfNull(arr); - ArgumentOutOfRangeException.ThrowIfNegative(start); - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(start, arr.Length); - - Range sliceRange = new(start, arr.Length - start); - return RuntimeHelpers.GetSubArray(arr, sliceRange); - } - - /// <summary> - /// Slices the current array by the specified starting offset to including the - /// speciifed number of items - /// </summary> - /// <typeparam name="T">The array type</typeparam> - /// <param name="arr"></param> - /// <param name="start">The start offset of the new array slice</param> - /// <param name="count">The size of the new array</param> - /// <returns>The sliced array</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static T[] Slice<T>(this T[] arr, int start, int count) - { - ArgumentNullException.ThrowIfNull(arr); - ArgumentOutOfRangeException.ThrowIfNegative(start); - ArgumentOutOfRangeException.ThrowIfNegative(count); - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(start + count, arr.Length); - - if(count == 0) - { - return []; - } - - //Calc the slice range - Range sliceRange = new(start, start + count); - return RuntimeHelpers.GetSubArray(arr, sliceRange); - } - - /// <summary> /// Creates a new sub-sequence over the target handle. (allows for convient sub span) /// </summary> /// <typeparam name="T"></typeparam> @@ -877,6 +833,7 @@ namespace VNLib.Utils.Extensions /// <returns>The sub-sequence of the current handle</returns> /// <exception cref="ArgumentOutOfRangeException"></exception> [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Obsolete("Functions are included directly on the type now")] public static Span<T> AsSpan<T>(this in UnsafeMemoryHandle<T> handle, int start) where T: unmanaged => handle.Span[start..]; /// <summary> @@ -889,6 +846,7 @@ namespace VNLib.Utils.Extensions /// <returns>The sub-sequence of the current handle</returns> /// <exception cref="ArgumentOutOfRangeException"></exception> [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Obsolete("Functions are included directly on the type now")] public static Span<T> AsSpan<T>(this in UnsafeMemoryHandle<T> handle, int start, int count) where T : unmanaged => handle.Span.Slice(start, count); /// <summary> diff --git a/lib/Utils/src/Memory/IMemoryHandle.cs b/lib/Utils/src/Memory/IMemoryHandle.cs index f4e1a36..b538f87 100644 --- a/lib/Utils/src/Memory/IMemoryHandle.cs +++ b/lib/Utils/src/Memory/IMemoryHandle.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Utils @@ -46,7 +46,7 @@ namespace VNLib.Utils.Memory /// <summary> /// Gets a reference to the first element in the block /// </summary> - /// <returns>The reference</returns> + /// <returns>The reference to the first element in the block</returns> ref T GetReference(); } diff --git a/lib/Utils/src/Memory/MemoryHandle.cs b/lib/Utils/src/Memory/MemoryHandle.cs index c5cc295..16fc555 100644 --- a/lib/Utils/src/Memory/MemoryHandle.cs +++ b/lib/Utils/src/Memory/MemoryHandle.cs @@ -188,8 +188,7 @@ namespace VNLib.Utils.Memory this.ThrowIfClosed(); //Get ptr and offset it - T* bs = ((T*)handle) + elements; - return bs; + return ((T*)handle) + elements; } ///<inheritdoc/> @@ -199,6 +198,16 @@ namespace VNLib.Utils.Memory return ref MemoryUtil.GetRef<T>(handle); } + /// <summary> + /// Gets a reference to the element at the specified offset from the base + /// address of the <see cref="MemoryHandle{T}"/> + /// </summary> + /// <param name="offset">The element offset from the base address to add to the returned reference</param> + /// <returns>The reference to the item at the desired offset</returns> + /// <exception cref="ArgumentOutOfRangeException"></exception> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe ref T GetOffsetRef(nuint offset) => ref Unsafe.AsRef<T>(GetOffset(offset)); + ///<inheritdoc/> ///<exception cref="ObjectDisposedException"></exception> ///<exception cref="ArgumentOutOfRangeException"></exception> @@ -248,6 +257,6 @@ namespace VNLib.Utils.Memory public override bool Equals(object? obj) => obj is MemoryHandle<T> oHandle && Equals(oHandle); ///<inheritdoc/> - public override int GetHashCode() => base.GetHashCode(); + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), handle.GetHashCode(), _length); } }
\ No newline at end of file diff --git a/lib/Utils/src/Memory/MemoryUtil.cs b/lib/Utils/src/Memory/MemoryUtil.cs index b6eadbc..7ce7c81 100644 --- a/lib/Utils/src/Memory/MemoryUtil.cs +++ b/lib/Utils/src/Memory/MemoryUtil.cs @@ -1349,6 +1349,51 @@ namespace VNLib.Utils.Memory public static MemoryHandle GetMemoryHandleFromPointer(IntPtr value, GCHandle handle = default, IPinnable? pinnable = null) => new (value.ToPointer(), handle, pinnable); + + /// <summary> + /// Slices the current array by the specified starting offset to the end + /// of the array + /// </summary> + /// <typeparam name="T">The array type</typeparam> + /// <param name="arr"></param> + /// <param name="start">The start offset of the new array slice</param> + /// <returns>The sliced array</returns> + /// <exception cref="ArgumentNullException"></exception> + /// <exception cref="ArgumentOutOfRangeException"></exception> + public static T[] SliceArray<T>(T[] arr, int start) + { + ArgumentNullException.ThrowIfNull(arr); + return SliceArray(arr, start, arr.Length - start); + } + + /// <summary> + /// Slices the current array by the specified starting offset to including the + /// speciifed number of items + /// </summary> + /// <typeparam name="T">The array type</typeparam> + /// <param name="arr"></param> + /// <param name="start">The start offset of the new array slice</param> + /// <param name="count">The size of the new array</param> + /// <returns>The sliced array</returns> + /// <exception cref="ArgumentNullException"></exception> + /// <exception cref="ArgumentOutOfRangeException"></exception> + public static T[] SliceArray<T>(T[] arr, int start, int count) + { + ArgumentNullException.ThrowIfNull(arr); + ArgumentOutOfRangeException.ThrowIfNegative(start); + ArgumentOutOfRangeException.ThrowIfNegative(count); + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(start + count, arr.Length); + + if (count == 0) + { + return []; + } + + //Calc the slice range + Range sliceRange = new(start, start + count); + return RuntimeHelpers.GetSubArray(arr, sliceRange); + } + /// <summary> /// Gets a <see cref="Span{T}"/> from the supplied address /// </summary> diff --git a/lib/Utils/src/Memory/UnsafeMemoryHandle.cs b/lib/Utils/src/Memory/UnsafeMemoryHandle.cs index fbf96eb..d93739d 100644 --- a/lib/Utils/src/Memory/UnsafeMemoryHandle.cs +++ b/lib/Utils/src/Memory/UnsafeMemoryHandle.cs @@ -49,8 +49,9 @@ namespace VNLib.Utils.Memory PrivateHeap } - private readonly IntPtr _memoryPtr; private readonly int _length; + + private readonly IntPtr _memoryPtr; private readonly HandleType _handleType; private readonly T[]? _poolArr; @@ -115,6 +116,11 @@ namespace VNLib.Utils.Memory [MethodImpl(MethodImplOptions.AggressiveInlining)] internal UnsafeMemoryHandle(IUnmangedHeap heap, IntPtr initial, int elements) { + //Never allow non-empty handles + Debug.Assert(heap != null); + Debug.Assert(initial != IntPtr.Zero); + Debug.Assert(elements > 0); + _pool = null; _poolArr = null; _heap = heap; @@ -196,6 +202,32 @@ namespace VNLib.Utils.Memory } } + /// <summary> + /// Returns a <see cref="Span{T}"/> that represents the memory block pointed to by this handle + /// </summary> + /// <returns>The memory block that is held by the internl handle</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly Span<T> AsSpan() => Span; + + /// <summary> + /// Returns a <see cref="Span{T}"/> that represents the memory block pointed to by this handle + /// </summary> + /// <param name="start">A starting element offset to return the span at</param> + /// <returns>The desired memory block at the desired element offset</returns> + /// <exception cref="ArgumentOutOfRangeException"></exception> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly Span<T> AsSpan(int start) => Span[start..]; + + /// <summary> + /// Returns a <see cref="Span{T}"/> that represents the memory block pointed to by this handle + /// </summary> + /// <param name="start">The starting element offset</param> + /// <param name="length">The number of elements included in the returned span</param> + /// <returns>The desired memory block at the desired element offset and length</returns> + /// <exception cref="ArgumentOutOfRangeException"></exception>" + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly Span<T> AsSpan(int start, int length) => Span.Slice(start, length); + ///<inheritdoc/> public readonly override int GetHashCode() { diff --git a/lib/Utils/src/Native/SafeLibraryHandle.cs b/lib/Utils/src/Native/SafeLibraryHandle.cs index 5fb2283..4b4ead4 100644 --- a/lib/Utils/src/Native/SafeLibraryHandle.cs +++ b/lib/Utils/src/Native/SafeLibraryHandle.cs @@ -63,9 +63,8 @@ namespace VNLib.Utils.Native { //Get the method pointer IntPtr nativeMethod = NativeLibrary.GetExport(handle, functionName); - //Get the delegate for the function pointer - T method = Marshal.GetDelegateForFunctionPointer<T>(nativeMethod); - return new(this, method); + AdvancedTrace.WriteLine($"Loaded function '{functionName}' with address: 0x'{nativeMethod:x}'"); + return new(this, Marshal.GetDelegateForFunctionPointer<T>(nativeMethod)); } catch { @@ -90,6 +89,7 @@ namespace VNLib.Utils.Native this.ThrowIfClosed(); //Get the method pointer IntPtr nativeMethod = NativeLibrary.GetExport(handle, functionName); + AdvancedTrace.WriteLine($"Loaded function '{functionName}' with address: 0x'{nativeMethod:x}'"); //Get the delegate for the function pointer return Marshal.GetDelegateForFunctionPointer<T>(nativeMethod); } @@ -97,6 +97,7 @@ namespace VNLib.Utils.Native ///<inheritdoc/> protected override bool ReleaseHandle() { + AdvancedTrace.WriteLine($"Releasing library handle: 0x'{handle:x}'"); //Free the library and set the handle as invalid NativeLibrary.Free(handle); SetHandleAsInvalid(); @@ -211,7 +212,9 @@ namespace VNLib.Utils.Native NatveLibraryResolver resolver = new(libPath, assembly, searchPath); - return resolver.ResolveAndLoadLibrary(out library); + bool success = resolver.ResolveAndLoadLibrary(out library); + AdvancedTrace.WriteLineIf(success, $"Loaded library '{libPath}' with address: 0x'{library?.DangerousGetHandle():x}'"); + return success; } } } diff --git a/lib/Utils/src/Resources/CallbackOpenHandle.cs b/lib/Utils/src/Resources/CallbackOpenHandle.cs deleted file mode 100644 index 625bd45..0000000 --- a/lib/Utils/src/Resources/CallbackOpenHandle.cs +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Copyright (c) 2022 Vaughn Nugent -* -* Library: VNLib -* Package: VNLib.Utils -* File: CallbackOpenHandle.cs -* -* CallbackOpenHandle.cs is part of VNLib.Utils which is part of the larger -* VNLib collection of libraries and utilities. -* -* VNLib.Utils is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 2 of the License, -* or (at your option) any later version. -* -* VNLib.Utils is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/. -*/ - -using System; - -namespace VNLib.Utils.Resources -{ - /// <summary> - /// A concrete <see cref="OpenHandle"/> for a defered operation or a resource that should be released or unwound - /// when the instance lifetime has ended. - /// </summary> - public sealed class CallbackOpenHandle : OpenHandle - { - private readonly Action ReleaseFunc; - /// <summary> - /// Creates a new generic <see cref="OpenHandle"/> with the specified release callback method - /// </summary> - /// <param name="release">The callback function to invoke when the <see cref="OpenHandle"/> is disposed</param> - public CallbackOpenHandle(Action release) => ReleaseFunc = release; - ///<inheritdoc/> - protected override void Free() => ReleaseFunc(); - } -}
\ No newline at end of file diff --git a/lib/Utils/src/Resources/ManagedLibrary.cs b/lib/Utils/src/Resources/ManagedLibrary.cs index 786a22d..c899156 100644 --- a/lib/Utils/src/Resources/ManagedLibrary.cs +++ b/lib/Utils/src/Resources/ManagedLibrary.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Utils @@ -25,7 +25,6 @@ using System; using System.IO; using System.Linq; -using System.Threading; using System.Reflection; using System.Runtime.Loader; using System.Collections.Generic; @@ -43,7 +42,7 @@ namespace VNLib.Utils.Resources { private readonly AssemblyLoadContext _loadContext; private readonly AssemblyDependencyResolver _resolver; - private readonly Lazy<Assembly> _lazyAssembly; + private readonly LazyInitializer<Assembly> _lazyAssembly; /// <summary> /// The absolute path to the assembly file @@ -53,7 +52,7 @@ namespace VNLib.Utils.Resources /// <summary> /// The assembly that is maintained by this loader /// </summary> - public Assembly Assembly => _lazyAssembly.Value; + public Assembly Assembly => _lazyAssembly.Instance; /// <summary> /// Initializes a new <see cref="ManagedLibrary"/> and skips @@ -74,11 +73,15 @@ namespace VNLib.Utils.Resources context.ResolvingUnmanagedDll += OnNativeLibraryResolving; //Lazy load the assembly - _lazyAssembly = new(LoadAssembly, LazyThreadSafetyMode.PublicationOnly); + _lazyAssembly = new(LoadAssembly); } //Load the assembly into the parent context - private Assembly LoadAssembly() => _loadContext.LoadFromAssemblyPath(AssemblyPath); + private Assembly LoadAssembly() + { + AdvancedTrace.WriteLine($"Loading managed library {AssemblyPath} into context {_loadContext.Name}"); + return _loadContext.LoadFromAssemblyPath(AssemblyPath); + } /// <summary> /// Raised when the load context that owns this assembly @@ -91,6 +94,7 @@ namespace VNLib.Utils.Resources /// </remarks> protected virtual void OnUnload(AssemblyLoadContext? ctx = null) { + AdvancedTrace.WriteLine($"Unloading managed library {AssemblyPath}"); //Remove resolving event handlers _loadContext.Unloading -= OnUnload; _loadContext.Resolving -= OnDependencyResolving; @@ -111,6 +115,8 @@ namespace VNLib.Utils.Resources //Resolve the desired asm dependency for the current context string? requestedDll = _resolver.ResolveUnmanagedDllToPath(libname); + AdvancedTrace.WriteLineIf(requestedDll != null,$"Resolving native library {libname} to path {requestedDll} for library {AssemblyPath}"); + //if the dep is resolved, seach in the assembly directory for the manageed dll only return requestedDll == null ? IntPtr.Zero : @@ -122,6 +128,8 @@ namespace VNLib.Utils.Resources //Resolve the desired asm dependency for the current context string? desiredAsm = _resolver.ResolveAssemblyToPath(asmName); + AdvancedTrace.WriteLineIf(desiredAsm != null, $"Resolving managed assembly {asmName.Name} to path {desiredAsm} for library {AssemblyPath}"); + //If the asm exists in the dir, load it return desiredAsm == null ? null : _loadContext.LoadFromAssemblyPath(desiredAsm); } @@ -137,6 +145,8 @@ namespace VNLib.Utils.Resources //See if the type is exported Type exp = TryGetExportedType<T>() ?? throw new EntryPointNotFoundException($"Imported assembly does not export desired type {typeof(T).FullName}"); + AdvancedTrace.WriteLine($"Creating instance of type {exp.FullName} from assembly {AssemblyPath}"); + //Create instance return (T)Activator.CreateInstance(exp)!; } diff --git a/lib/Utils/src/VNLib.Utils.csproj b/lib/Utils/src/VNLib.Utils.csproj index bda2164..7941a7b 100644 --- a/lib/Utils/src/VNLib.Utils.csproj +++ b/lib/Utils/src/VNLib.Utils.csproj @@ -26,6 +26,10 @@ <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance> </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> + <DefineConstants>$(DefineConstants);VNLIB_ADVANCED_TRACING</DefineConstants> + </PropertyGroup> + <ItemGroup> <None Include="..\README.md"> <Pack>True</Pack> |