worker(alarms): UnAdvise only advised handles in LmxSubtagAlarmSource teardown
B3: track advised handles separately from added handles so Dispose only UnAdvises items that were actually advised — a write-only subtag (e.g. ack-comment added by Write, never advised) is removed but not unadvised. Add Dispose tests covering the advised/write-only split, full removal, single Unregister, and double-dispose idempotency.
This commit is contained in:
@@ -46,6 +46,12 @@ public sealed class LmxSubtagAlarmSource : ISubtagAlarmSource
|
||||
private readonly Dictionary<int, string> addressesByItemHandle =
|
||||
new Dictionary<int, string>();
|
||||
|
||||
// Handles that were actually Advise()d, tracked separately from the added
|
||||
// set so Dispose only UnAdvises advised items. Write() can AddItem a
|
||||
// write-only subtag (e.g. an ack-comment that was never advised); calling
|
||||
// UnAdvise on such a handle would be an unbalanced teardown.
|
||||
private readonly HashSet<int> advisedItemHandles = new HashSet<int>();
|
||||
|
||||
private object? mxAccessComObject;
|
||||
private IMxAccessServer? server;
|
||||
private LMXProxyServerClass? comEventSource;
|
||||
@@ -134,6 +140,7 @@ public sealed class LmxSubtagAlarmSource : ISubtagAlarmSource
|
||||
mxServer.Advise(serverHandle, itemHandle);
|
||||
itemHandlesByAddress[itemAddress!] = itemHandle;
|
||||
addressesByItemHandle[itemHandle] = itemAddress!;
|
||||
advisedItemHandles.Add(itemHandle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +232,13 @@ public sealed class LmxSubtagAlarmSource : ISubtagAlarmSource
|
||||
{
|
||||
foreach (KeyValuePair<int, string> entry in addressesByItemHandle)
|
||||
{
|
||||
try { mxServer.UnAdvise(serverHandle, entry.Key); } catch { /* swallow — best effort */ }
|
||||
// Only UnAdvise handles that were actually advised; a write-only
|
||||
// item (added by Write but never Advise'd) was never advised.
|
||||
if (advisedItemHandles.Contains(entry.Key))
|
||||
{
|
||||
try { mxServer.UnAdvise(serverHandle, entry.Key); } catch { /* swallow — best effort */ }
|
||||
}
|
||||
|
||||
try { mxServer.RemoveItem(serverHandle, entry.Key); } catch { /* swallow — best effort */ }
|
||||
}
|
||||
|
||||
@@ -234,6 +247,7 @@ public sealed class LmxSubtagAlarmSource : ISubtagAlarmSource
|
||||
|
||||
itemHandlesByAddress.Clear();
|
||||
addressesByItemHandle.Clear();
|
||||
advisedItemHandles.Clear();
|
||||
|
||||
object? comToRelease = mxAccessComObject;
|
||||
mxAccessComObject = null;
|
||||
|
||||
Reference in New Issue
Block a user