The deadlock situation is craaaaazy

Fix
This commit is contained in:
Evil Factory
2026-01-19 21:20:04 -03:00
committed by Maplewheels
parent dda26df250
commit f1e1b9238d
4 changed files with 51 additions and 51 deletions

View File

@@ -235,6 +235,12 @@ public sealed class ModConfigService : IModConfigService
private async Task<Result<IModConfigInfo>> CreateFromLegacyAsync(ContentPackage src)
{
throw new NotImplementedException();
return new ModConfigInfo()
{
Package = src,
Assemblies = ImmutableArray<IAssemblyResourceInfo>.Empty,
Configs = ImmutableArray<IConfigResourceInfo>.Empty,
LuaScripts = ImmutableArray<ILuaScriptResourceInfo>.Empty
};
}
}

View File

@@ -25,8 +25,8 @@ public class SafeStorageService : StorageService, ISafeStorageService
public SafeStorageService(IStorageServiceConfig configData) : base(configData)
{
IsReadOperationAllowedEval = async Task<bool> (fp) => IsFileAccessible(fp, true, true);
IsWriteOperationAllowedEval = async Task<bool> (fp) => IsFileAccessible(fp, false, true);
IsReadOperationAllowedEval = (fp) => IsFileAccessible(fp, true, true);
IsWriteOperationAllowedEval = (fp) => IsFileAccessible(fp, false, true);
}
private string GetFullPath(string path) => System.IO.Path.GetFullPath(path).CleanUpPathCrossPlatform();

View File

@@ -17,7 +17,10 @@ public class ServicesProvider : IServicesProvider
public ServicesProvider()
{
_serviceContainerInst = new ServiceContainer();
_serviceContainerInst = new ServiceContainer(new ContainerOptions()
{
EnablePropertyInjection = false
});
}
public void RegisterServiceType<TSvcInterface, TService>(ServiceLifetime lifetime, ILifetime lifetimeInstance = null) where TSvcInterface : class, IService where TService : class, IService, TSvcInterface

View File

@@ -23,27 +23,16 @@ public class StorageService : IStorageService
public StorageService(IStorageServiceConfig configData)
{
ConfigData = configData;
IsReadOperationAllowedEval = async Task<bool> (str) => true;
IsWriteOperationAllowedEval = async Task<bool> (str) => true;
}
public StorageService(IStorageServiceConfig configData,
Func<string, Task<bool>> isReadOperationAllowedEval,
Func<string, Task<bool>> isWriteOperationAllowedEval)
{
Guard.IsNotNull(isReadOperationAllowedEval, nameof(isReadOperationAllowedEval));
Guard.IsNotNull(isWriteOperationAllowedEval, nameof(isWriteOperationAllowedEval));
ConfigData = configData;
IsReadOperationAllowedEval = isReadOperationAllowedEval;
IsWriteOperationAllowedEval = isWriteOperationAllowedEval;
IsReadOperationAllowedEval = bool (str) => true;
IsWriteOperationAllowedEval = bool (str) => true;
}
private readonly ConcurrentDictionary<string, OneOf.OneOf<byte[], string, XDocument>> _fsCache = new();
protected readonly IStorageServiceConfig ConfigData;
protected readonly AsyncReaderWriterLock OperationsLock = new();
private Func<string, Task<bool>> _isReadOperationAllowedEval;
protected Func<string, Task<bool>> IsReadOperationAllowedEval
private Func<string, bool> _isReadOperationAllowedEval;
protected Func<string, bool> IsReadOperationAllowedEval
{
get => _isReadOperationAllowedEval;
set
@@ -53,8 +42,8 @@ public class StorageService : IStorageService
}
}
private Func<string, Task<bool>> _isWriteOperationAllowedEval;
protected Func<string, Task<bool>> IsWriteOperationAllowedEval
private Func<string, bool> _isWriteOperationAllowedEval;
protected Func<string, bool> IsWriteOperationAllowedEval
{
get => _isWriteOperationAllowedEval;
set
@@ -221,25 +210,28 @@ public class StorageService : IStorageService
public async Task<FluentResults.Result> SaveLocalTextAsync(ContentPackage package, string localFilePath, string text)
=> await SaveLocalDataAsync(package, localFilePath, text, async (path, txt) => await TrySaveTextAsync(path, txt));
private bool IsPackagePathValid(ContentPath contentPath)
{
return contentPath.FullPath.StartsWith(ConfigData.WorkshopModsDirectory)
|| contentPath.FullPath.StartsWith(ConfigData.LocalModsDirectory)
#if CLIENT
|| contentPath.FullPath.StartsWith(ConfigData.TempDownloadsDirectory)
#endif
|| contentPath.FullPath.StartsWith(Path.GetFullPath(ContentPackageManager.VanillaCorePackage!.Dir).CleanUpPathCrossPlatform());
}
// --- Package Content
private Result<T> LoadPackageData<T>(ContentPath filePath, Func<string, Result<T>> dataLoader)
private Result<T> LoadPackageData<T>(ContentPath contentPath, Func<string, Result<T>> dataLoader)
{
Guard.IsNotNull(filePath, nameof(filePath));
Guard.IsNotNullOrWhiteSpace(filePath.FullPath, nameof(filePath.FullPath));
Guard.IsNotNull(contentPath, nameof(contentPath));
Guard.IsNotNullOrWhiteSpace(contentPath.FullPath, nameof(contentPath.FullPath));
using var lck = OperationsLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
IService.CheckDisposed(this);
if (!filePath.FullPath.StartsWith(ConfigData.WorkshopModsDirectory)
&& !filePath.FullPath.StartsWith(ConfigData.LocalModsDirectory)
&& !filePath.FullPath.StartsWith(ContentPackageManager.VanillaCorePackage!.Dir)
#if CLIENT
&& !filePath.FullPath.StartsWith(ConfigData.TempDownloadsDirectory)
#endif
)
if (!IsPackagePathValid(contentPath))
{
ThrowHelper.ThrowUnauthorizedAccessException($"{nameof(LoadPackageData)}: The filepath of `{filePath.FullPath}' is not in a package directory!");
ThrowHelper.ThrowUnauthorizedAccessException($"{nameof(LoadPackageData)}: The filepath of `{contentPath.FullPath}' is not in a package directory!");
}
return dataLoader(filePath.FullPath);
return dataLoader(contentPath.FullPath);
}
public Result<XDocument> LoadPackageXml(ContentPath filePath)
@@ -292,18 +284,17 @@ public class StorageService : IStorageService
}
private async Task<Result<T>> LoadPackageDataAsync<T>(ContentPath filePath, Func<string, Task<Result<T>>> dataLoader)
private async Task<Result<T>> LoadPackageDataAsync<T>(ContentPath contentPath, Func<string, Task<Result<T>>> dataLoader)
{
Guard.IsNotNull(filePath, nameof(filePath));
Guard.IsNotNullOrWhiteSpace(filePath.FullPath, nameof(filePath.FullPath));
Guard.IsNotNull(contentPath, nameof(contentPath));
Guard.IsNotNullOrWhiteSpace(contentPath.FullPath, nameof(contentPath.FullPath));
using var lck = await OperationsLock.AcquireReaderLock();
IService.CheckDisposed(this);
if (!filePath.FullPath.StartsWith(ConfigData.WorkshopModsDirectory) && !filePath.FullPath.StartsWith(ConfigData.LocalModsDirectory))
if (!IsPackagePathValid(contentPath))
{
ThrowHelper.ThrowUnauthorizedAccessException(
$"{nameof(LoadPackageData)}: The filepath of `{filePath.FullPath}' is not in a package directory!");
ThrowHelper.ThrowUnauthorizedAccessException($"{nameof(LoadPackageDataAsync)}: The filepath of `{contentPath.FullPath}' is not in a package directory!");
}
return await dataLoader(filePath.FullPath);
return await dataLoader(contentPath.FullPath);
}
public async Task<Result<XDocument>> LoadPackageXmlAsync(ContentPath filePath)
@@ -371,7 +362,7 @@ public class StorageService : IStorageService
using var lck = OperationsLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
IService.CheckDisposed(this);
if (IsReadOperationAllowedEval?.Invoke(filePath).ConfigureAwait(false).GetAwaiter().GetResult() is not true)
if (IsReadOperationAllowedEval?.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TryLoadText)}: File '{filePath}' is not allowed.");
}
@@ -399,7 +390,7 @@ public class StorageService : IStorageService
using var lck = OperationsLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
IService.CheckDisposed(this);
if (IsReadOperationAllowedEval?.Invoke(filePath).ConfigureAwait(false).GetAwaiter().GetResult() is not true)
if (IsReadOperationAllowedEval?.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TryLoadBinary)}: File '{filePath}' is not allowed.");
}
@@ -430,7 +421,7 @@ public class StorageService : IStorageService
using var lck = OperationsLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
IService.CheckDisposed(this);
if (IsWriteOperationAllowedEval?.Invoke(filePath).ConfigureAwait(false).GetAwaiter().GetResult() is not true)
if (IsWriteOperationAllowedEval?.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TrySaveText)}: File '{filePath}' is not allowed.");
}
@@ -456,7 +447,7 @@ public class StorageService : IStorageService
using var lck = OperationsLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
IService.CheckDisposed(this);
if (IsWriteOperationAllowedEval?.Invoke(filePath).ConfigureAwait(false).GetAwaiter().GetResult() is not true)
if (IsWriteOperationAllowedEval?.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TrySaveBinary)}: File '{filePath}' is not allowed.");
}
@@ -479,7 +470,7 @@ public class StorageService : IStorageService
Guard.IsNotNullOrWhiteSpace(filePath, nameof(filePath));
IService.CheckDisposed(this);
// lock not needed
if (IsReadOperationAllowedEval?.Invoke(filePath).ConfigureAwait(false).GetAwaiter().GetResult() is not true)
if (IsReadOperationAllowedEval?.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(FileExists)}: File '{filePath}' is not allowed.");
}
@@ -497,7 +488,7 @@ public class StorageService : IStorageService
Guard.IsNotNullOrWhiteSpace(directoryPath, nameof(directoryPath));
IService.CheckDisposed(this);
// lock not needed
if (IsReadOperationAllowedEval?.Invoke(directoryPath).ConfigureAwait(false).GetAwaiter().GetResult() is not true)
if (IsReadOperationAllowedEval?.Invoke(directoryPath) is not true)
{
return FluentResults.Result.Fail($"{nameof(DirectoryExists)}: File '{directoryPath}' is not allowed.");
}
@@ -518,7 +509,7 @@ public class StorageService : IStorageService
Guard.IsNotNullOrWhiteSpace(filePath, nameof(filePath));
using var lck = await OperationsLock.AcquireReaderLock();
IService.CheckDisposed(this);
if (await IsReadOperationAllowedEval.Invoke(filePath) is not true)
if (IsReadOperationAllowedEval.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TryLoadXmlAsync)}: File '{filePath}' is not allowed.");
}
@@ -548,7 +539,7 @@ public class StorageService : IStorageService
Guard.IsNotNullOrWhiteSpace(filePath, nameof(filePath));
using var lck = await OperationsLock.AcquireReaderLock();
IService.CheckDisposed(this);
if (await IsReadOperationAllowedEval.Invoke(filePath) is not true)
if (IsReadOperationAllowedEval.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TryLoadTextAsync)}: File '{filePath}' is not allowed.");
}
@@ -575,7 +566,7 @@ public class StorageService : IStorageService
Guard.IsNotNullOrWhiteSpace(filePath, nameof(filePath));
using var lck = await OperationsLock.AcquireReaderLock();
IService.CheckDisposed(this);
if (await IsReadOperationAllowedEval.Invoke(filePath) is not true)
if (IsReadOperationAllowedEval.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TryLoadBinaryAsync)}: File '{filePath}' is not allowed.");
}
@@ -601,7 +592,7 @@ public class StorageService : IStorageService
Guard.IsNotNullOrWhiteSpace(text, nameof(text));
using var lck = await OperationsLock.AcquireReaderLock();
IService.CheckDisposed(this);
if (await IsWriteOperationAllowedEval.Invoke(filePath) is not true)
if (IsWriteOperationAllowedEval.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TrySaveTextAsync)}: File '{filePath}' is not allowed.");
}
@@ -625,7 +616,7 @@ public class StorageService : IStorageService
Guard.HasSizeGreaterThanOrEqualTo(bytes, 1, nameof(bytes));
using var lck = await OperationsLock.AcquireReaderLock();
IService.CheckDisposed(this);
if (await IsWriteOperationAllowedEval.Invoke(filePath) is not true)
if (IsWriteOperationAllowedEval.Invoke(filePath) is not true)
{
return FluentResults.Result.Fail($"{nameof(TrySaveBinaryAsync)}: File '{filePath}' is not allowed.");
}