Skip to content

Commit

Permalink
Add System.Threading.Lock (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyrrrz authored Sep 2, 2024
1 parent 5c2a6ae commit e571bf4
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 0 deletions.
93 changes: 93 additions & 0 deletions PolyShim.Tests/Net90/LockTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System.Threading;
using FluentAssertions;
using Xunit;

namespace PolyShim.Tests.Net90;

public class LockTests
{
[Fact]
public void Enter_Test()
{
// Arrange
var syncRoot = new Lock();

// Act & assert
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
syncRoot.Enter();
syncRoot.IsHeldByCurrentThread.Should().BeTrue();
}

[Fact]
public void TryEnter_Test()
{
// Arrange
var syncRoot = new Lock();

// Act & assert
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
syncRoot.TryEnter().Should().BeTrue();
syncRoot.IsHeldByCurrentThread.Should().BeTrue();
}

[Fact]
public void TryEnter_Timeout_Test()
{
// Arrange
var syncRoot = new Lock();

// Act & assert
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
syncRoot.TryEnter(100).Should().BeTrue();
syncRoot.IsHeldByCurrentThread.Should().BeTrue();
}

[Fact]
public void Exit_Test()
{
// Arrange
var syncRoot = new Lock();

// Act & assert
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
syncRoot.Enter();
syncRoot.IsHeldByCurrentThread.Should().BeTrue();
syncRoot.Exit();
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
}

[Fact]
public void EnterScope_Test()
{
// Arrange
var syncRoot = new Lock();

// Act & assert
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
using (syncRoot.EnterScope())
{
syncRoot.IsHeldByCurrentThread.Should().BeTrue();
}
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
}

[Fact]
public void EnterScope_Layered_Test()
{
// Arrange
var syncRoot = new Lock();

// Act & assert
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
using (syncRoot.EnterScope())
{
syncRoot.IsHeldByCurrentThread.Should().BeTrue();
using (syncRoot.EnterScope())
{
syncRoot.IsHeldByCurrentThread.Should().BeTrue();
}
syncRoot.IsHeldByCurrentThread.Should().BeTrue();
}
syncRoot.IsHeldByCurrentThread.Should().BeFalse();
}
}
42 changes: 42 additions & 0 deletions PolyShim/Net90/Lock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#if (NETCOREAPP && !NET9_0_OR_GREATER) || (NETFRAMEWORK) || (NETSTANDARD)

This comment has been minimized.

Copy link
@MarkCiliaVincenti

MarkCiliaVincenti Sep 29, 2024

This lock class is not hardened against thread aborts coming from framework versions preceding .NET 5.0.

Consider using Backport.System.Threading.Lock instead of this method for locking.

#nullable enable
#pragma warning disable CS9216
// ReSharper disable RedundantUsingDirective
// ReSharper disable CheckNamespace
// ReSharper disable InconsistentNaming
// ReSharper disable PartialTypeWithSinglePart

namespace System.Threading;

internal partial class Lock
{
#if (NETCOREAPP) || (NETFRAMEWORK && NET45_OR_GREATER) || (NETSTANDARD)
public bool IsHeldByCurrentThread => Monitor.IsEntered(this);
#endif

public void Enter() => Monitor.Enter(this);

public bool TryEnter() => Monitor.TryEnter(this);

public bool TryEnter(TimeSpan timeout) => Monitor.TryEnter(this, timeout);

public bool TryEnter(int millisecondsTimeout) =>
TryEnter(TimeSpan.FromMilliseconds(millisecondsTimeout));

public void Exit() => Monitor.Exit(this);

public Scope EnterScope()
{
Enter();
return new Scope(this);
}
}

internal partial class Lock
{
public readonly ref struct Scope(Lock owner)
{
public void Dispose() => owner.Exit();
}
}
#endif

0 comments on commit e571bf4

Please sign in to comment.