Browse Source

Make sure that unlock API is still safe.

pull/2918/head
Dariusz Komosinski 7 years ago
parent
commit
edd6fd626f
  1. 23
      src/Avalonia.Native/AvaloniaNativeDeferredRendererLock.cs
  2. 26
      src/Avalonia.Visuals/Rendering/ManagedDeferredRendererLock.cs

23
src/Avalonia.Native/AvaloniaNativeDeferredRendererLock.cs

@ -1,5 +1,8 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Reactive.Disposables;
using System.Threading;
using Avalonia.Native.Interop;
using Avalonia.Rendering;
@ -13,11 +16,27 @@ namespace Avalonia.Native
{
_window = window;
}
public IDisposable TryLock()
{
if (_window.TryLock())
return Disposable.Create(() => _window.Unlock());
return new UnlockDisposable(_window);
return null;
}
private class UnlockDisposable : IDisposable
{
private IAvnWindowBase _window;
public UnlockDisposable(IAvnWindowBase window)
{
_window = window;
}
public void Dispose()
{
Interlocked.Exchange(ref _window, null)?.Unlock();
}
}
}
}

26
src/Avalonia.Visuals/Rendering/ManagedDeferredRendererLock.cs

@ -1,3 +1,6 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Threading;
@ -6,12 +9,6 @@ namespace Avalonia.Rendering
public class ManagedDeferredRendererLock : IDeferredRendererLock
{
private readonly object _lock = new object();
private readonly LockDisposable _lockDisposable;
public ManagedDeferredRendererLock()
{
_lockDisposable = new LockDisposable(_lock);
}
/// <summary>
/// Tries to lock the target surface or window
@ -20,7 +17,7 @@ namespace Avalonia.Rendering
public IDisposable TryLock()
{
if (Monitor.TryEnter(_lock))
return _lockDisposable;
return new UnlockDisposable(_lock);
return null;
}
@ -30,21 +27,26 @@ namespace Avalonia.Rendering
public IDisposable Lock()
{
Monitor.Enter(_lock);
return _lockDisposable;
return new UnlockDisposable(_lock);
}
private class LockDisposable : IDisposable
private class UnlockDisposable : IDisposable
{
private readonly object _lock;
private object _lock;
public LockDisposable(object @lock)
public UnlockDisposable(object @lock)
{
_lock = @lock;
}
public void Dispose()
{
Monitor.Exit(_lock);
object @lock = Interlocked.Exchange(ref _lock, null);
if (@lock != null)
{
Monitor.Exit(@lock);
}
}
}
}

Loading…
Cancel
Save