From ab3f910a76568d8a0c234aee0227c65705729da8 Mon Sep 17 00:00:00 2001 From: Mathias Dobler <81033366+huesla@users.noreply.github.com> Date: Mon, 18 Mar 2024 06:54:29 +0100 Subject: [PATCH] Do not pass static zero IntPtr to epoll wait. Dispose driver in tests in all cases. (#2291) --- src/System.Device.Gpio.Tests/GpioControllerTestBase.cs | 8 ++++---- src/System.Device.Gpio/Interop/UnmanagedArray.cs | 5 +---- .../System/Device/Gpio/Drivers/SysFsDriver.cs | 8 +++++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/System.Device.Gpio.Tests/GpioControllerTestBase.cs b/src/System.Device.Gpio.Tests/GpioControllerTestBase.cs index 8be336df11..c2fd94c396 100644 --- a/src/System.Device.Gpio.Tests/GpioControllerTestBase.cs +++ b/src/System.Device.Gpio.Tests/GpioControllerTestBase.cs @@ -28,7 +28,7 @@ protected GpioControllerTestBase(ITestOutputHelper testOutputHelper) [InlineData(false)] public void PinValueStaysSameAfterDispose(bool closeAsHigh) { - var driver = GetTestDriver(); + using var driver = GetTestDriver(); if (driver is SysFsDriver) { // This check fails on the SysFsDriver, because it always sets the value to 0 when the pin is opened (but on close, the value does stay high) @@ -181,7 +181,7 @@ public void ThrowsIfWritingClosedPin() [Trait("SkipOnTestRun", "Windows_NT")] // Currently, the Windows Driver is defaulting to InputPullDown, and it seems this cannot be changed public void OpenPinDefaultsModeToLastMode(PinMode modeToTest) { - var driver = GetTestDriver(); + using var driver = GetTestDriver(); if (driver is SysFsDriver) { // See issue #1581. There seems to be a library-version issue or some other random cause for this test to act differently on different hardware. @@ -230,7 +230,7 @@ void Callback(object sender, PinValueChangedEventArgs pinValueChangedEventArgs) [Fact] public void AddCallbackFallingEdgeNotDetectedTest() { - var driver = GetTestDriver(); + using var driver = GetTestDriver(); if (driver is SysFsDriver) { // This test is unreliable (flaky) with SysFs. @@ -317,7 +317,7 @@ void Callback(object sender, PinValueChangedEventArgs e) [Fact] public void AddCallbackRemoveAllCallbackTest() { - GpioDriver testDriver = GetTestDriver(); + using GpioDriver testDriver = GetTestDriver(); // Skipping the test for now when using the SysFsDriver or the RaspberryPi3Driver given that this test is flaky for those drivers. // Issue tracking this problem is https://github.com/dotnet/iot/issues/629 if (testDriver is SysFsDriver || testDriver is RaspberryPi3Driver) diff --git a/src/System.Device.Gpio/Interop/UnmanagedArray.cs b/src/System.Device.Gpio/Interop/UnmanagedArray.cs index df2b4c4295..b96dac7856 100644 --- a/src/System.Device.Gpio/Interop/UnmanagedArray.cs +++ b/src/System.Device.Gpio/Interop/UnmanagedArray.cs @@ -10,8 +10,6 @@ internal sealed class UnmanagedArray : SafeHandle private readonly int _arrayLength; private readonly int _typeSize; - public static readonly UnmanagedArray Empty = new(0); - public UnmanagedArray(int arrayLength) : base(IntPtr.Zero, true) { @@ -21,7 +19,7 @@ public UnmanagedArray(int arrayLength) } _arrayLength = arrayLength; - _typeSize = Marshal.SizeOf(typeof(T)); + _typeSize = Marshal.SizeOf(); SetHandle(Marshal.AllocHGlobal(_typeSize * arrayLength)); } @@ -58,4 +56,3 @@ public static implicit operator IntPtr(UnmanagedArray unmanagedArray) return !unmanagedArray.IsInvalid ? unmanagedArray.handle : throw new InvalidOperationException("Invalid handle"); } } - diff --git a/src/System.Device.Gpio/System/Device/Gpio/Drivers/SysFsDriver.cs b/src/System.Device.Gpio/System/Device/Gpio/Drivers/SysFsDriver.cs index a2877d5c6c..5bf0d062d7 100644 --- a/src/System.Device.Gpio/System/Device/Gpio/Drivers/SysFsDriver.cs +++ b/src/System.Device.Gpio/System/Device/Gpio/Drivers/SysFsDriver.cs @@ -456,7 +456,8 @@ private void AddPinToPoll(int pinNumber, ref int valueFileDescriptor, ref int po } // Ignore first time because it will always return the current state. - while (Interop.epoll_wait(pollFileDescriptor, UnmanagedArray.Empty, 1, 0) == -1) + using var eventBuffer = new UnmanagedArray(1); + while (Interop.epoll_wait(pollFileDescriptor, eventBuffer, 1, 0) == -1) { var errorCode = Marshal.GetLastWin32Error(); if (errorCode != ERROR_CODE_EINTR) @@ -467,14 +468,15 @@ private void AddPinToPoll(int pinNumber, ref int valueFileDescriptor, ref int po } } - private unsafe bool WasEventDetected(int pollFileDescriptor, int valueFileDescriptor, out int pinNumber, CancellationToken cancellationToken) + private bool WasEventDetected(int pollFileDescriptor, int valueFileDescriptor, out int pinNumber, CancellationToken cancellationToken) { pinNumber = -1; + using var eventBuffer = new UnmanagedArray(1); + while (!cancellationToken.IsCancellationRequested) { // Wait until something happens - using var eventBuffer = new UnmanagedArray(1); int waitResult = Interop.epoll_wait(pollFileDescriptor, eventBuffer, 1, PollingTimeout); if (waitResult == -1) {