From e2695db0118aa0f9448c34cb88f8cbd4f53162de Mon Sep 17 00:00:00 2001 From: MapleWheels Date: Thu, 26 Oct 2023 16:25:01 -0400 Subject: [PATCH] - Fixed ACL name not being shown in warnings. - Fixed thread lock recursion causing fileloadexceptions. --- .../LuaCs/Plugins/AssemblyManager.cs | 14 ++++++- .../LuaCs/Plugins/CsPackageManager.cs | 5 ++- .../MemoryFileAssemblyContextLoader.cs | 38 +++++++++++++------ 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs index 566276687..352485437 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs @@ -352,13 +352,25 @@ public class AssemblyManager { OpsLockLoaded.ExitReadLock(); } - } #endregion #region InternalAPI + /// + /// [Unsafe] Warning: only for use in nested threading functions. Requires care to manage access. + /// Does not make any guarantees about the state of the ACL after the list has been returned. + /// + /// + [MethodImpl(MethodImplOptions.Synchronized | MethodImplOptions.NoInlining)] + internal ImmutableList UnsafeGetAllLoadedACLs() + { + if (LoadedACLs.IsEmpty) + return ImmutableList.Empty; + return LoadedACLs.Select(kvp => kvp.Value).ToImmutableList(); + } + /// /// Used by content package and plugin management to stop unloading of a given ACL until all plugins have gracefully closed. /// diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs index a92f0ea38..77de3a722 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs @@ -295,15 +295,16 @@ public sealed class CsPackageManager : IDisposable _assemblyManager.OnAssemblyUnloading += AssemblyManagerOnAssemblyUnloading; // log error if some ACLs are still unloading (some assembly is still in use) + _assemblyManager.FinalizeDispose(); //Update lists if (_assemblyManager.IsCurrentlyUnloading) { ModUtils.Logging.PrintWarning($"WARNING: Some mods from a previous session (lobby) are still loaded! This may result in undefined behaviour!\nIf you notice any odd behaviour that only occurs after multiple lobbies, please restart your game."); + ModUtils.Logging.PrintWarning($"The below ACLs are still unloading:"); foreach (var wkref in _assemblyManager.StillUnloadingACLs) { - ModUtils.Logging.PrintWarning($"The below ACL is still unloading:"); if (wkref.TryGetTarget(out var tgt)) { - ModUtils.Logging.PrintWarning($"ACL Name: {tgt.Name}"); + ModUtils.Logging.PrintWarning($"ACL Name: {tgt.FriendlyName}"); foreach (Assembly assembly in tgt.Assemblies) { ModUtils.Logging.PrintWarning($"-- Assembly: {assembly.GetName()}"); diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs index 94e3edd74..e99bdfe2d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs @@ -280,20 +280,33 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext } //try resolve against other loaded alcs - foreach (var loadedAcL in _assemblyManager.GetAllLoadedACLs()) + ImmutableList list; + try { - if (loadedAcL.Acl is null || loadedAcL.Acl.IsTemplateMode || loadedAcL.Acl.IsDisposed) - continue; + list = _assemblyManager.UnsafeGetAllLoadedACLs(); + } + catch + { + list = ImmutableList.Empty; + } + + if (!list.IsEmpty) + { + foreach (var loadedAcL in list) + { + if (loadedAcL.Acl is null || loadedAcL.Acl.IsTemplateMode || loadedAcL.Acl.IsDisposed) + continue; - try - { - ass = loadedAcL.Acl.LoadFromAssemblyName(assemblyName); - if (ass is not null) - return ass; - } - catch - { - // LoadFromAssemblyName throws, no need to propagate + try + { + ass = loadedAcL.Acl.LoadFromAssemblyName(assemblyName); + if (ass is not null) + return ass; + } + catch + { + // LoadFromAssemblyName throws, no need to propagate + } } } @@ -315,6 +328,7 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext CompiledAssembly = null; CompiledAssemblyImage = null; _dependencyResolvers.Clear(); + _assemblyManager = null; base.Unloading -= OnUnload; this.IsDisposed = true; }