From 655bfe36a6faca44126e379ac98f8c1a7456c188 Mon Sep 17 00:00:00 2001 From: Kyro Date: Fri, 26 Oct 2018 13:30:43 +1300 Subject: [PATCH] Fix NullReferenceException when calling Lock.Acquire with a CancellationToken that gets cancelled. --- Consul.Test/LockTest.cs | 23 ++++++++++++++++++++++- Consul/Lock.cs | 12 +++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Consul.Test/LockTest.cs b/Consul.Test/LockTest.cs index 7ab99ed..c91e319 100644 --- a/Consul.Test/LockTest.cs +++ b/Consul.Test/LockTest.cs @@ -38,7 +38,7 @@ public void Dispose() { m_lock.Dispose(); } - + [Fact] public async Task Lock_AcquireRelease() { @@ -669,5 +669,26 @@ public async Task Lock_DeleteKey() } } } + + [Fact] + public async Task Lock_AcquireTimeout() + { + using (var client = new ConsulClient()) + { + const string keyName = "test/lock/acquiretimeout"; + var distributedLock = await client.AcquireLock(keyName); + try + { + using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5))) + { + await Assert.ThrowsAsync(() => client.AcquireLock(keyName, cts.Token)); + } + } + finally + { + await distributedLock.Release(); + } + } + } } } \ No newline at end of file diff --git a/Consul/Lock.cs b/Consul/Lock.cs index 0f0bdfa..540f0b2 100644 --- a/Consul/Lock.cs +++ b/Consul/Lock.cs @@ -331,11 +331,21 @@ public async Task Acquire(CancellationToken ct) if (ct.IsCancellationRequested || (!IsHeld && !string.IsNullOrEmpty(Opts.Session))) { DisposeCancellationTokenSource(); - if (_sessionRenewTask != null) + if (_monitorTask != null) { try { await _monitorTask.ConfigureAwait(false); + } + catch (AggregateException) + { + // Ignore AggregateExceptions from the tasks during Release, since if the Monitor task died, the developer will be Super Confused if they see the exception during Release. + } + } + if (_sessionRenewTask != null) + { + try + { await _sessionRenewTask.ConfigureAwait(false); } catch (AggregateException)