From 05101f0e0e1c2198fe323ab7967a5b673853db48 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Fri, 30 Oct 2020 00:19:57 +0100 Subject: [PATCH] Improve exception handling of AsyncLock. --- Source/MQTTnet/Internal/AsyncLock.cs | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/Source/MQTTnet/Internal/AsyncLock.cs b/Source/MQTTnet/Internal/AsyncLock.cs index 210364ab..d3c94f85 100644 --- a/Source/MQTTnet/Internal/AsyncLock.cs +++ b/Source/MQTTnet/Internal/AsyncLock.cs @@ -7,9 +7,11 @@ namespace MQTTnet.Internal // From Stephen Toub (https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/) public sealed class AsyncLock : IDisposable { - readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); + readonly object _syncRoot = new object(); readonly Task _releaser; + SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); + public AsyncLock() { _releaser = Task.FromResult((IDisposable)new Releaser(this)); @@ -36,21 +38,33 @@ namespace MQTTnet.Internal public void Dispose() { - _semaphore?.Dispose(); + lock (_syncRoot) + { + _semaphore?.Dispose(); + _semaphore = null; + } } - class Releaser : IDisposable + internal void Release() { - readonly AsyncLock _toRelease; - - internal Releaser(AsyncLock toRelease) + lock (_syncRoot) { - _toRelease = toRelease; + _semaphore?.Release(); + } + } + + sealed class Releaser : IDisposable + { + readonly AsyncLock _lock; + + internal Releaser(AsyncLock @lock) + { + _lock = @lock; } public void Dispose() { - _toRelease._semaphore.Release(); + _lock.Release(); } } }