70 lines
2.1 KiB
C#
70 lines
2.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using io.github.hatayama.uLoopMCP.Factory;
|
|
|
|
namespace io.github.hatayama.uLoopMCP
|
|
{
|
|
internal sealed class DynamicCodeExecutorPool : IDynamicCodeExecutorPool
|
|
{
|
|
private readonly IDynamicCodeExecutorProvider _executorProvider;
|
|
private readonly Dictionary<DynamicCodeSecurityLevel, IDynamicCodeExecutor> _executorsBySecurityLevel = new();
|
|
private readonly object _executorsLock = new();
|
|
private bool _disposed;
|
|
|
|
public DynamicCodeExecutorPool(IDynamicCodeExecutorProvider executorProvider)
|
|
{
|
|
_executorProvider = executorProvider ?? throw new ArgumentNullException(nameof(executorProvider));
|
|
}
|
|
|
|
public IDynamicCodeExecutor GetOrCreate(DynamicCodeSecurityLevel securityLevel)
|
|
{
|
|
lock (_executorsLock)
|
|
{
|
|
ThrowIfDisposed();
|
|
|
|
if (_executorsBySecurityLevel.TryGetValue(securityLevel, out IDynamicCodeExecutor executor))
|
|
{
|
|
return executor;
|
|
}
|
|
|
|
IDynamicCodeExecutor createdExecutor = _executorProvider.Create(securityLevel);
|
|
if (createdExecutor is DynamicCodeExecutorStub)
|
|
{
|
|
return createdExecutor;
|
|
}
|
|
|
|
_executorsBySecurityLevel.Add(securityLevel, createdExecutor);
|
|
return createdExecutor;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
lock (_executorsLock)
|
|
{
|
|
if (_disposed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_disposed = true;
|
|
|
|
foreach (IDynamicCodeExecutor executor in _executorsBySecurityLevel.Values)
|
|
{
|
|
executor.Dispose();
|
|
}
|
|
|
|
_executorsBySecurityLevel.Clear();
|
|
}
|
|
}
|
|
|
|
private void ThrowIfDisposed()
|
|
{
|
|
if (_disposed)
|
|
{
|
|
throw new ObjectDisposedException(nameof(DynamicCodeExecutorPool));
|
|
}
|
|
}
|
|
}
|
|
}
|