Resolve stale pointer issues (#1711)

* Resolve stale pointer issues

* remove unncessary FrameworkOnBeforeUpdate

---------

Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
rootdarkarchon 2024-03-14 05:41:02 +01:00 committed by GitHub
parent 1128d93fec
commit 2721e2df16
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -26,12 +26,11 @@ namespace Dalamud.Game.ClientState.Objects;
#pragma warning disable SA1015 #pragma warning disable SA1015
[ResolveVia<IObjectTable>] [ResolveVia<IObjectTable>]
#pragma warning restore SA1015 #pragma warning restore SA1015
internal sealed partial class ObjectTable : IServiceType, IObjectTable, IDisposable internal sealed partial class ObjectTable : IServiceType, IObjectTable
{ {
private const int ObjectTableLength = 599; private const int ObjectTableLength = 599;
private readonly ClientState clientState; private readonly ClientState clientState;
private readonly Framework framework;
private readonly CachedEntry[] cachedObjectTable = new CachedEntry[ObjectTableLength]; private readonly CachedEntry[] cachedObjectTable = new CachedEntry[ObjectTableLength];
private readonly ObjectPool<Enumerator> multiThreadedEnumerators = private readonly ObjectPool<Enumerator> multiThreadedEnumerators =
@ -42,16 +41,14 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable, IDisposa
private long nextMultithreadedUsageWarnTime; private long nextMultithreadedUsageWarnTime;
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
private ObjectTable(ClientState clientState, Framework framework) private ObjectTable(ClientState clientState)
{ {
this.clientState = clientState; this.clientState = clientState;
this.framework = framework;
foreach (ref var e in this.cachedObjectTable.AsSpan()) foreach (ref var e in this.cachedObjectTable.AsSpan())
e = CachedEntry.CreateNew(); e = CachedEntry.CreateNew();
for (var i = 0; i < this.frameworkThreadEnumerators.Length; i++) for (var i = 0; i < this.frameworkThreadEnumerators.Length; i++)
this.frameworkThreadEnumerators[i] = new(this, i); this.frameworkThreadEnumerators[i] = new(this, i);
framework.BeforeUpdate += this.FrameworkOnBeforeUpdate;
Log.Verbose($"Object table address 0x{this.clientState.AddressResolver.ObjectTable.ToInt64():X}"); Log.Verbose($"Object table address 0x{this.clientState.AddressResolver.ObjectTable.ToInt64():X}");
} }
@ -76,7 +73,9 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable, IDisposa
{ {
_ = this.WarnMultithreadedUsage(); _ = this.WarnMultithreadedUsage();
return index is >= ObjectTableLength or < 0 ? null : this.cachedObjectTable[index].ActiveObject; if (index is >= ObjectTableLength or < 0) return null;
this.cachedObjectTable[index].Update(this.GetObjectAddressUnsafe(index));
return this.cachedObjectTable[index].ActiveObject;
} }
} }
@ -135,12 +134,6 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable, IDisposa
}; };
} }
/// <inheritdoc />
public void Dispose()
{
this.framework.BeforeUpdate -= this.FrameworkOnBeforeUpdate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool WarnMultithreadedUsage() private bool WarnMultithreadedUsage()
{ {
@ -161,12 +154,6 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable, IDisposa
return true; return true;
} }
private void FrameworkOnBeforeUpdate(IFramework unused)
{
for (var i = 0; i < ObjectTableLength; i++)
this.cachedObjectTable[i].Update(this.GetObjectAddressUnsafe(i));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe nint GetObjectAddressUnsafe(int index) => private unsafe nint GetObjectAddressUnsafe(int index) =>
*(nint*)(this.clientState.AddressResolver.ObjectTable + (8 * index)); *(nint*)(this.clientState.AddressResolver.ObjectTable + (8 * index));
@ -192,6 +179,9 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable, IDisposa
public unsafe void Update(nint address) public unsafe void Update(nint address)
{ {
if (this.ActiveObject != null && address == this.ActiveObject.Address)
return;
if (address == nint.Zero) if (address == nint.Zero)
{ {
this.ActiveObject = null; this.ActiveObject = null;