From b86f2df89ba8d9cd192c8464ff2f5a9baf50e5f1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Jun 2026 20:40:52 +0000 Subject: [PATCH 1/7] Initial plan From cffcfbbda1e0081380fa3aaaa215062495da7da0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Jun 2026 20:43:17 +0000 Subject: [PATCH 2/7] chore: update plan for finalizer removal --- .../Comm and IR/ComPortController.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs index ec679fae..5d81ead2 100644 --- a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs +++ b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs @@ -119,6 +119,9 @@ namespace PepperDash.Essentials.Core /// ~ComPortController() { + if (Port == null) + return; + Port.SerialDataReceived -= Port_SerialDataReceived; } @@ -156,6 +159,9 @@ namespace PepperDash.Essentials.Core /// public override bool Deactivate() { + if (Port == null) + return false; + return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success; } From 1681d4e796599fd12721c4e8022be7b8e6e4aefc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Jun 2026 20:43:52 +0000 Subject: [PATCH 3/7] fix: remove ComPortController finalizer and harden deactivate cleanup --- .../Comm and IR/ComPortController.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs index 5d81ead2..aa644678 100644 --- a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs +++ b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs @@ -114,17 +114,6 @@ namespace PepperDash.Essentials.Core Port.SerialDataReceived += Port_SerialDataReceived; } - /// - /// Destructor - /// - ~ComPortController() - { - if (Port == null) - return; - - Port.SerialDataReceived -= Port_SerialDataReceived; - } - void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args) { OnDataReceived(args.SerialData); @@ -162,6 +151,7 @@ namespace PepperDash.Essentials.Core if (Port == null) return false; + Port.SerialDataReceived -= Port_SerialDataReceived; return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success; } From 148dead020685ed2f7ceb65c0acc3ed3d2163d8e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Jun 2026 20:46:08 +0000 Subject: [PATCH 4/7] fix: treat null com port as already deactivated --- src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs index aa644678..3dfd8632 100644 --- a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs +++ b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs @@ -149,7 +149,7 @@ namespace PepperDash.Essentials.Core public override bool Deactivate() { if (Port == null) - return false; + return true; Port.SerialDataReceived -= Port_SerialDataReceived; return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success; From a2388acf6428ba5d5a694520f8832eca2aa5fb1c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Jun 2026 17:06:54 +0000 Subject: [PATCH 5/7] fix: deactivate ComPortController on program stopping event --- .../Comm and IR/ComPortController.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs index 3dfd8632..8b28d23b 100644 --- a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs +++ b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs @@ -50,6 +50,7 @@ namespace PepperDash.Essentials.Core ComPort.ComPortSpec spec, EssentialsControlPropertiesConfig config) : base(key) { StreamDebugging = new CommunicationStreamDebugging(key); + CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; Spec = spec; @@ -70,6 +71,8 @@ namespace PepperDash.Essentials.Core public ComPortController(string key, ComPort port, ComPort.ComPortSpec spec) : base(key) { + CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; + if (port == null) { Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Invalid com port, continuing but comms will not function"); @@ -142,6 +145,12 @@ namespace PepperDash.Essentials.Core if (!eventSubscribed) Debug.LogMessage(LogEventLevel.Warning, this, "Received data but no handler is registered"); } + void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) + { + if (programEventType == eProgramStatusEventType.Stopping) + Deactivate(); + } + /// /// Deactivate method /// From cd8bfcfbdc8028991291b38ced311211ca70b212 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Jun 2026 17:09:30 +0000 Subject: [PATCH 6/7] fix: make ComPortController shutdown deactivation idempotent --- .../Comm and IR/ComPortController.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs index 8b28d23b..0bc71c62 100644 --- a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs +++ b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs @@ -38,6 +38,8 @@ namespace PepperDash.Essentials.Core ComPort Port; ComPort.ComPortSpec Spec; + private readonly object _deactivateLock = new object(); + private bool _isDeactivated; /// /// Constructor @@ -148,7 +150,9 @@ namespace PepperDash.Essentials.Core void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) { if (programEventType == eProgramStatusEventType.Stopping) + { Deactivate(); + } } /// @@ -157,6 +161,16 @@ namespace PepperDash.Essentials.Core /// public override bool Deactivate() { + lock (_deactivateLock) + { + if (_isDeactivated) + return true; + + _isDeactivated = true; + } + + CrestronEnvironment.ProgramStatusEventHandler -= CrestronEnvironment_ProgramStatusEventHandler; + if (Port == null) return true; From d4f1fecc64e5090a9aa1f5043943c3f044055ab3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Jun 2026 17:11:18 +0000 Subject: [PATCH 7/7] fix: register ComPort shutdown hook after initialization --- .../Comm and IR/ComPortController.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs index 0bc71c62..e6a9773f 100644 --- a/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs +++ b/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs @@ -52,7 +52,6 @@ namespace PepperDash.Essentials.Core ComPort.ComPortSpec spec, EssentialsControlPropertiesConfig config) : base(key) { StreamDebugging = new CommunicationStreamDebugging(key); - CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; Spec = spec; @@ -62,6 +61,8 @@ namespace PepperDash.Essentials.Core RegisterAndConfigureComPort(); }); + + CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; } /// @@ -73,8 +74,6 @@ namespace PepperDash.Essentials.Core public ComPortController(string key, ComPort port, ComPort.ComPortSpec spec) : base(key) { - CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; - if (port == null) { Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Invalid com port, continuing but comms will not function"); @@ -86,6 +85,7 @@ namespace PepperDash.Essentials.Core //IsConnected = new BoolFeedback(CommonBoolCue.IsConnected, () => true); RegisterAndConfigureComPort(); + CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; } private void RegisterAndConfigureComPort()