diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/PlcTagHandle.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/PlcTagHandle.cs deleted file mode 100644 index cc6189c..0000000 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/PlcTagHandle.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Runtime.InteropServices; - -namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip; - -/// -/// wrapper around a libplctag native tag handle (an int32 -/// returned from plc_tag_create_ex). Owns lifetime of the native allocation so a -/// leaked / GC-collected still calls plc_tag_destroy -/// during finalization — necessary because native libplctag allocations are opaque to -/// the driver's . -/// -/// -/// Risk documented in driver-specs.md §3 ("Operational Stability Notes"): the CLR -/// allocation tracker doesn't see libplctag's native heap, only whole-process RSS can. -/// Every handle leaked past its useful life is a direct contributor to the Tier-B recycle -/// trigger, so owning lifetime via SafeHandle is non-negotiable. -/// -/// is true when the native ID is <= 0 — libplctag -/// returns negative PLCTAG_ERR_* codes on plc_tag_create_ex failure, which -/// we surface as an invalid handle rather than a disposable one (destroying a negative -/// handle would be undefined behavior in the native library). -/// -/// The actual DllImport for plc_tag_destroy is deferred to PR 3 when -/// the driver first makes wire calls — PR 2 ships the lifetime scaffold + tests only. -/// Until the P/Invoke lands, is a no-op; the finalizer still -/// runs so the integration is correct as soon as the import is added. -/// -public sealed class PlcTagHandle : SafeHandle -{ - /// Construct an invalid handle placeholder (use once created). - public PlcTagHandle() : base(invalidHandleValue: IntPtr.Zero, ownsHandle: true) { } - - private PlcTagHandle(int nativeId) : base(invalidHandleValue: IntPtr.Zero, ownsHandle: true) - { - SetHandle(new IntPtr(nativeId)); - } - - /// Handle is invalid when the native ID is zero or negative (libplctag error). - public override bool IsInvalid => handle.ToInt32() <= 0; - - /// Integer ID libplctag issued on plc_tag_create_ex. - public int NativeId => handle.ToInt32(); - - /// Wrap a native tag ID returned from libplctag. - public static PlcTagHandle FromNative(int nativeId) => new(nativeId); - - /// - /// Destroy the native tag. No-op for PR 2 (the wire P/Invoke lands in PR 3). The base - /// machinery still guarantees this runs exactly once per - /// handle — either during or during finalization - /// if the owner was GC'd without explicit Dispose. - /// - protected override bool ReleaseHandle() - { - if (IsInvalid) return true; - // PR 3: wire up plc_tag_destroy(handle.ToInt32()) once the DllImport lands. - return true; - } -}