potential resolve disposal crashes and race conditions

This commit is contained in:
choco
2025-12-21 22:34:39 +01:00
parent 34bbc34b5b
commit 0ec423e65c

View File

@@ -1,4 +1,4 @@
using Dalamud.Plugin.Services;
using Dalamud.Plugin.Services;
using LightlessSync.API.Dto.User;
using LightlessSync.Services.ActorTracking;
using LightlessSync.Services.Mediator;
@@ -33,6 +33,7 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
private const int _maxQueueSize = 100;
private volatile bool _batchRunning = false;
private volatile bool _disposed = false;
public IReadOnlyDictionary<string, BroadcastEntry> BroadcastCache => _broadcastCache;
public readonly record struct BroadcastEntry(bool IsBroadcasting, DateTime ExpiryTime, string? GID);
@@ -63,6 +64,9 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
public void Update()
{
if (_disposed)
return;
_frameCounter++;
var lookupsThisFrame = 0;
@@ -104,7 +108,14 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
private async Task BatchUpdateBroadcastCacheAsync(List<string> cids)
{
if (_disposed)
return;
var results = await _broadcastService.AreUsersBroadcastingAsync(cids).ConfigureAwait(false);
if (_disposed)
return;
var now = DateTime.UtcNow;
foreach (var (cid, info) in results)
@@ -123,6 +134,9 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
(_, old) => new BroadcastEntry(info.IsBroadcasting, expiry, info.GID));
}
if (_disposed)
return;
var activeCids = _broadcastCache
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now)
.Select(e => e.Key)
@@ -134,6 +148,9 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
private void OnBroadcastStatusChanged(BroadcastStatusChangedMessage msg)
{
if (_disposed)
return;
if (!msg.Enabled)
{
_broadcastCache.Clear();
@@ -147,6 +164,9 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
private void UpdateSyncshellBroadcasts()
{
if (_disposed)
return;
var now = DateTime.UtcNow;
var newSet = _broadcastCache
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now && !string.IsNullOrEmpty(e.Value.GID))
@@ -230,17 +250,35 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
protected override void Dispose(bool disposing)
{
_disposed = true;
base.Dispose(disposing);
_framework.Update -= OnFrameworkUpdate;
if (_cleanupTask != null)
try
{
_cleanupTask?.Wait(100, _cleanupCts.Token);
_cleanupCts.Cancel();
}
catch (ObjectDisposedException)
{
// Already disposed, can be ignored :)
}
_cleanupCts.Cancel();
_cleanupCts.Dispose();
try
{
_cleanupTask?.Wait(100);
}
catch (Exception)
{
// Task may have already completed or been cancelled?
}
_cleanupTask?.Wait(100);
_cleanupCts.Dispose();
try
{
_cleanupCts.Dispose();
}
catch (ObjectDisposedException)
{
// Already disposed, ignore
}
}
}