mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-26 07:39:52 -06:00

* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Address dotnet format CA1822 warnings * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Revert formatting changes for while and for-loops * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Add comments to disabled warnings * Remove a few unused parameters * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Address IDE0251 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Add trailing commas and fix formatting issues * Convert if-else chain to switch block * Address review feedback
253 lines
7.0 KiB
C#
253 lines
7.0 KiB
C#
using Ryujinx.Horizon.Common;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
|
{
|
|
class ServerDomainManager
|
|
{
|
|
private class EntryManager
|
|
{
|
|
public class Entry
|
|
{
|
|
public int Id { get; }
|
|
public Domain Owner { get; set; }
|
|
public ServiceObjectHolder Obj { get; set; }
|
|
public LinkedListNode<Entry> Node { get; set; }
|
|
|
|
public Entry(int id)
|
|
{
|
|
Id = id;
|
|
}
|
|
}
|
|
|
|
private readonly LinkedList<Entry> _freeList;
|
|
private readonly Entry[] _entries;
|
|
|
|
public EntryManager(int count)
|
|
{
|
|
_freeList = new LinkedList<Entry>();
|
|
_entries = new Entry[count];
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
_freeList.AddLast(_entries[i] = new Entry(i + 1));
|
|
}
|
|
}
|
|
|
|
public Entry AllocateEntry()
|
|
{
|
|
lock (_freeList)
|
|
{
|
|
if (_freeList.Count == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var entry = _freeList.First.Value;
|
|
_freeList.RemoveFirst();
|
|
return entry;
|
|
}
|
|
}
|
|
|
|
public void FreeEntry(Entry entry)
|
|
{
|
|
lock (_freeList)
|
|
{
|
|
DebugUtil.Assert(entry.Owner == null);
|
|
DebugUtil.Assert(entry.Obj == null);
|
|
_freeList.AddFirst(entry);
|
|
}
|
|
}
|
|
|
|
public Entry GetEntry(int id)
|
|
{
|
|
if (id == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
int index = id - 1;
|
|
|
|
if ((uint)index >= (uint)_entries.Length)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return _entries[index];
|
|
}
|
|
}
|
|
|
|
private class Domain : DomainServiceObject, IDisposable
|
|
{
|
|
private readonly ServerDomainManager _manager;
|
|
private readonly LinkedList<EntryManager.Entry> _entries;
|
|
|
|
public Domain(ServerDomainManager manager)
|
|
{
|
|
_manager = manager;
|
|
_entries = new LinkedList<EntryManager.Entry>();
|
|
}
|
|
|
|
public override ServiceObjectHolder GetObject(int id)
|
|
{
|
|
var entry = _manager._entryManager.GetEntry(id);
|
|
if (entry == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
lock (_manager._entryOwnerLock)
|
|
{
|
|
if (entry.Owner != this)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
return entry.Obj.Clone();
|
|
}
|
|
|
|
public override ServerDomainBase GetServerDomain()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
public override void RegisterObject(int id, ServiceObjectHolder obj)
|
|
{
|
|
var entry = _manager._entryManager.GetEntry(id);
|
|
DebugUtil.Assert(entry != null);
|
|
|
|
lock (_manager._entryOwnerLock)
|
|
{
|
|
DebugUtil.Assert(entry.Owner == null);
|
|
entry.Owner = this;
|
|
entry.Node = _entries.AddLast(entry);
|
|
}
|
|
|
|
entry.Obj = obj;
|
|
}
|
|
|
|
public override Result ReserveIds(Span<int> outIds)
|
|
{
|
|
for (int i = 0; i < outIds.Length; i++)
|
|
{
|
|
var entry = _manager._entryManager.AllocateEntry();
|
|
if (entry == null)
|
|
{
|
|
return SfResult.OutOfDomainEntries;
|
|
}
|
|
|
|
DebugUtil.Assert(entry.Owner == null);
|
|
|
|
outIds[i] = entry.Id;
|
|
}
|
|
|
|
return Result.Success;
|
|
}
|
|
|
|
public override ServiceObjectHolder UnregisterObject(int id)
|
|
{
|
|
var entry = _manager._entryManager.GetEntry(id);
|
|
if (entry == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
ServiceObjectHolder obj;
|
|
|
|
lock (_manager._entryOwnerLock)
|
|
{
|
|
if (entry.Owner != this)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
entry.Owner = null;
|
|
obj = entry.Obj;
|
|
|
|
if (obj.ServiceObject is IDisposable disposableObj)
|
|
{
|
|
disposableObj.Dispose();
|
|
}
|
|
|
|
entry.Obj = null;
|
|
_entries.Remove(entry.Node);
|
|
entry.Node = null;
|
|
}
|
|
|
|
_manager._entryManager.FreeEntry(entry);
|
|
|
|
return obj;
|
|
}
|
|
|
|
public override void UnreserveIds(ReadOnlySpan<int> ids)
|
|
{
|
|
for (int i = 0; i < ids.Length; i++)
|
|
{
|
|
var entry = _manager._entryManager.GetEntry(ids[i]);
|
|
|
|
DebugUtil.Assert(entry != null);
|
|
DebugUtil.Assert(entry.Owner == null);
|
|
|
|
_manager._entryManager.FreeEntry(entry);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
foreach (var entry in _entries)
|
|
{
|
|
if (entry.Obj.ServiceObject is IDisposable disposableObj)
|
|
{
|
|
disposableObj.Dispose();
|
|
}
|
|
}
|
|
|
|
_manager.FreeDomain(this);
|
|
}
|
|
}
|
|
|
|
private readonly EntryManager _entryManager;
|
|
private readonly object _entryOwnerLock;
|
|
private readonly HashSet<Domain> _domains;
|
|
private readonly int _maxDomains;
|
|
|
|
public ServerDomainManager(int entryCount, int maxDomains)
|
|
{
|
|
_entryManager = new EntryManager(entryCount);
|
|
_entryOwnerLock = new object();
|
|
_domains = new HashSet<Domain>();
|
|
_maxDomains = maxDomains;
|
|
}
|
|
|
|
public DomainServiceObject AllocateDomainServiceObject()
|
|
{
|
|
lock (_domains)
|
|
{
|
|
if (_domains.Count == _maxDomains)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var domain = new Domain(this);
|
|
_domains.Add(domain);
|
|
return domain;
|
|
}
|
|
}
|
|
|
|
public static void DestroyDomainServiceObject(DomainServiceObject obj)
|
|
{
|
|
((Domain)obj).Dispose();
|
|
}
|
|
|
|
private void FreeDomain(Domain domain)
|
|
{
|
|
lock (_domains)
|
|
{
|
|
_domains.Remove(domain);
|
|
}
|
|
}
|
|
}
|
|
}
|