Skip to content

Conversation

@felixcollins
Copy link
Contributor

@felixcollins felixcollins commented Sep 18, 2025

The interrupt state monitoring in the driver is not ideal. I hit a bug where the previous pin state had not been set before an interrupt was received from the chip. Not surprising really as any line on the chip could cause the interrupt. By initialising the pin state dict before signing up for the interrupt we will avoid this issue.

This PR also removes the lock in the end of the interrupt handling task and substitutes using a ConcurrentDictionary. The way it was being done, by copying the whole pin state dict, could lead to concurrency bugs due to pin states added during the task running being effectively removed when the whole dict was replaced.

Microsoft Reviewers: Open in CodeFlow

…nterrupts started flooding in during startup.

(cherry picked from commit 11a84419fc77a38e6ce07f335beb6c2b9ae56618)
@dotnet-policy-service dotnet-policy-service bot added the area-device-bindings Device Bindings for audio, sensor, motor, and display hardware that can used with System.Device.Gpio label Sep 18, 2025
throw new InvalidOperationException("No interrupt pin configured");
}

lock (_interruptHandlerLock)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why you prefer the lock instead of the ConcurrentDictionary for this as well?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes interrupt state monitoring bugs in the Tca955x GPIO driver. The main issue addressed is a race condition where interrupts could occur before the driver's internal state was properly initialized, leading to KeyNotFoundException when accessing pin states.

  • Initialize interrupt state dictionaries during construction to prevent race conditions
  • Replace lock-based state updates with ConcurrentDictionary to avoid concurrency bugs
  • Rename variables for better clarity and fix event handler management logic

_interruptLastInputValues = interruptLastInputValuesSnapshot;
foreach (var pin in interruptLastInputValuesSnapshot.Keys)
{
_interruptLastInputValues.TryUpdate(pin, interruptLastInputValuesSnapshot[pin], !interruptLastInputValuesSnapshot[pin]);
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TryUpdate call uses !interruptLastInputValuesSnapshot[pin] as the comparison value, which appears incorrect. TryUpdate expects the current value to compare against, not the inverse of the new value. This should likely be the actual current value from the ConcurrentDictionary or use TryAdd/AddOrUpdate instead.

Suggested change
_interruptLastInputValues.TryUpdate(pin, interruptLastInputValuesSnapshot[pin], !interruptLastInputValuesSnapshot[pin]);
_interruptLastInputValues.TryUpdate(pin, interruptLastInputValuesSnapshot[pin], interruptLastInputValuesSnapshot[pin]);

Copilot uses AI. Check for mistakes.
else
_interruptPinsSubscribedEvents[pinNumber] = eventType;
var currentValue = Read(pinNumber);
_interruptLastInputValues.TryUpdate(pinNumber, currentValue, !currentValue);
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to line 507, this TryUpdate call uses !currentValue as the comparison value, which is incorrect. The third parameter should be the expected current value in the dictionary, not the inverse of the new value being set.

Suggested change
_interruptLastInputValues.TryUpdate(pinNumber, currentValue, !currentValue);
_interruptLastInputValues.TryUpdate(pinNumber, currentValue, currentValue);

Copilot uses AI. Check for mistakes.
@felixcollins
Copy link
Contributor Author

felixcollins commented Sep 25, 2025 via email

@felixcollins
Copy link
Contributor Author

felixcollins commented Sep 25, 2025 via email

@raffaeler
Copy link
Contributor

@felixcollins Yes, the changes were already there, but I believe there is the opportunity to make this code a bit better :) I will try to trigger the copilot again to see what happens

@raffaeler
Copy link
Contributor

@copilot read the latest comments and fix your review. Add comments to clarify the intent of the new or revised code.

@raffaeler raffaeler requested a review from Copilot September 26, 2025 07:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@krwq
Copy link
Member

krwq commented Oct 2, 2025

[Triage] We discussed this briefly and this is good as is. We can address anything else separately

@krwq krwq merged commit ead23d6 into dotnet:main Oct 2, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-device-bindings Device Bindings for audio, sensor, motor, and display hardware that can used with System.Device.Gpio

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants