Skip to content

Commit

Permalink
Fix a merge problem
Browse files Browse the repository at this point in the history
  • Loading branch information
pgrawehr committed Apr 27, 2024
1 parent be654e6 commit 1f4b066
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 72 deletions.
58 changes: 29 additions & 29 deletions src/System.Device.Gpio.Tests/LibGpiodDriverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,37 +71,37 @@ static void PinChanged(object sender, PinValueChangedEventArgs args)
gc.UnregisterCallbackForPinValueChangedEvent(InputPin, PinChanged);
}
}
}

/// <summary>
/// Ensure leaking instances of the driver doesn't cause a segfault
/// Regression test for https://github.com/dotnet/iot/issues/1849
/// </summary>
[Fact]
public void LeakingDriverDoesNotCrash()
{
GpioController controller1 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller1.OpenPin(10, PinMode.Output);
GpioController controller2 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller2.OpenPin(11, PinMode.Output);
GpioController controller3 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller3.OpenPin(12, PinMode.Output);
GpioController controller4 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller4.OpenPin(13, PinMode.Output);
GpioController controller5 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller5.OpenPin(14, PinMode.Output);

for (int i = 0; i < 10; i++)
{
GC.Collect();
GpioController controller6 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller6.OpenPin(15, PinMode.Output);
controller6.ClosePin(15);
controller6.Dispose();
GC.Collect();
Thread.Sleep(20);
}
/// <summary>
/// Ensure leaking instances of the driver doesn't cause a segfault
/// Regression test for https://github.com/dotnet/iot/issues/1849
/// </summary>
[Fact]
public void LeakingDriverDoesNotCrash()
{
GpioController controller1 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller1.OpenPin(10, PinMode.Output);
GpioController controller2 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller2.OpenPin(11, PinMode.Output);
GpioController controller3 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller3.OpenPin(12, PinMode.Output);
GpioController controller4 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller4.OpenPin(13, PinMode.Output);
GpioController controller5 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller5.OpenPin(14, PinMode.Output);

GC.WaitForPendingFinalizers();
for (int i = 0; i < 10; i++)
{
GC.Collect();
GpioController controller6 = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver());
controller6.OpenPin(15, PinMode.Output);
controller6.ClosePin(15);
controller6.Dispose();
GC.Collect();
Thread.Sleep(20);
}

GC.WaitForPendingFinalizers();
}
}
85 changes: 42 additions & 43 deletions src/System.Device.Gpio/Interop/Unix/SafeLineHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,61 @@

using System.Runtime.InteropServices;

namespace System.Device.Gpio
namespace System.Device.Gpio;

/// <summary>
/// Pointer to a pin (Not a real SafeLineHandle, because we need to align its finalization with the owning object)
/// </summary>
internal sealed class SafeLineHandle : IDisposable
{
/// <summary>
/// Pointer to a pin (Not a real SafeLineHandle, because we need to align its finalization with the owning object)
/// </summary>
internal sealed class SafeLineHandle : IDisposable
private IntPtr _handle;
public SafeLineHandle()
{
private IntPtr _handle;
public SafeLineHandle()
{
_handle = IntPtr.Zero;
}
_handle = IntPtr.Zero;
}

public SafeLineHandle(IntPtr handle)
{
_handle = handle;
PinMode = PinMode.Input;
}
public SafeLineHandle(IntPtr handle)
{
_handle = handle;
PinMode = PinMode.Input;
}

public PinMode PinMode { get; set; }
public PinMode PinMode { get; set; }

public IntPtr Handle
public IntPtr Handle
{
get
{
get
{
return _handle;
}
set
{
_handle = value;
}
return _handle;
}

/// <summary>
/// Release the lock on the line handle. <see cref="Interop.libgpiod.gpiod_line_release"/>
/// </summary>
public void ReleaseLock()
set
{
// Contrary to intuition, this does not invalidate the handle (see comment on declaration)
Interop.libgpiod.gpiod_line_release(_handle);
_handle = value;
}
}

public bool IsInvalid => _handle == IntPtr.Zero || _handle == Interop.libgpiod.InvalidHandleValue;
/// <summary>
/// Release the lock on the line handle. <see cref="Interop.libgpiod.gpiod_line_release"/>
/// </summary>
public void ReleaseLock()
{
// Contrary to intuition, this does not invalidate the handle (see comment on declaration)
Interop.libgpiod.gpiod_line_release(_handle);
}

public void Dispose()
{
if (_handle != IntPtr.Zero)
{
Interop.libgpiod.gpiod_line_release(_handle);
_handle = IntPtr.Zero;
}
}
public bool IsInvalid => _handle == IntPtr.Zero || _handle == Interop.libgpiod.InvalidHandleValue;

public static implicit operator IntPtr(SafeLineHandle self)
public void Dispose()
{
if (_handle != IntPtr.Zero)
{
return self.Handle;
Interop.libgpiod.gpiod_line_release(_handle);
_handle = IntPtr.Zero;
}
}

public static implicit operator IntPtr(SafeLineHandle self)
{
return self.Handle;
}
}

0 comments on commit 1f4b066

Please sign in to comment.