Skip to content

Commit

Permalink
Added a shared/reusable implementation for multi-locking within strea…
Browse files Browse the repository at this point in the history
…m operators, I.E. being able to process upstream notifications and downstream notifications at the same time, with different locks, while still preserving notification order. (#893)
  • Loading branch information
JakenVeina authored May 22, 2024
1 parent 76fd915 commit a02c6d6
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/DynamicData/Internal/SwappableLock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2011-2023 Roland Pheasant. All rights reserved.
// Roland Pheasant licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

namespace DynamicData;

internal ref struct SwappableLock
{
public static SwappableLock CreateAndEnter(object gate)
{
var result = new SwappableLock()
{
_gate = gate
};

Monitor.Enter(gate, ref result._hasLock);

return result;
}

public void SwapTo(object gate)
{
if (_gate is null)
throw new InvalidOperationException("Lock is not initialized");

var hasNewLock = false;
Monitor.Enter(gate, ref hasNewLock);

if (_hasLock)
Monitor.Exit(_gate);

_hasLock = hasNewLock;
_gate = gate;
}

public void Dispose()
{
if (_hasLock && (_gate is not null))
{
Monitor.Exit(_gate);
_hasLock = false;
_gate = null;
}
}

private bool _hasLock;
private object? _gate;
}

0 comments on commit a02c6d6

Please sign in to comment.