diff --git a/src/NHibernate/Async/Cache/UpdateTimestampsCache.cs b/src/NHibernate/Async/Cache/UpdateTimestampsCache.cs index 2bfb9719618..53bc686f5eb 100644 --- a/src/NHibernate/Async/Cache/UpdateTimestampsCache.cs +++ b/src/NHibernate/Async/Cache/UpdateTimestampsCache.cs @@ -11,8 +11,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; - using NHibernate.Cfg; using NHibernate.Util; @@ -51,20 +49,26 @@ public Task PreInvalidateAsync(object[] spaces, CancellationToken cancellationTo } } - public virtual async Task PreInvalidateAsync(IReadOnlyCollection spaces, CancellationToken cancellationToken) + public virtual Task PreInvalidateAsync(IReadOnlyCollection spaces, CancellationToken cancellationToken) { - cancellationToken.ThrowIfCancellationRequested(); - if (spaces.Count == 0) - return; - cancellationToken.ThrowIfCancellationRequested(); - - using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + try { + if (spaces.Count == 0) + return Task.CompletedTask; + //TODO: to handle concurrent writes correctly, this should return a Lock to the client var ts = _updateTimestamps.NextTimestamp() + _updateTimestamps.Timeout; - await (SetSpacesTimestampAsync(spaces, ts, cancellationToken)).ConfigureAwait(false); + return SetSpacesTimestampAsync(spaces, ts, cancellationToken); //TODO: return new Lock(ts); } + catch (Exception ex) + { + return Task.FromException(ex); + } } //Since v5.1 @@ -86,21 +90,27 @@ public Task InvalidateAsync(object[] spaces, CancellationToken cancellationToken } } - public virtual async Task InvalidateAsync(IReadOnlyCollection spaces, CancellationToken cancellationToken) + public virtual Task InvalidateAsync(IReadOnlyCollection spaces, CancellationToken cancellationToken) { - cancellationToken.ThrowIfCancellationRequested(); - if (spaces.Count == 0) - return; - cancellationToken.ThrowIfCancellationRequested(); - - using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + try { + if (spaces.Count == 0) + return Task.CompletedTask; + //TODO: to handle concurrent writes correctly, the client should pass in a Lock long ts = _updateTimestamps.NextTimestamp(); //TODO: if lock.getTimestamp().equals(ts) if (log.IsDebugEnabled()) log.Debug("Invalidating spaces [{0}]", StringHelper.CollectionToString(spaces)); - await (SetSpacesTimestampAsync(spaces, ts, cancellationToken)).ConfigureAwait(false); + return SetSpacesTimestampAsync(spaces, ts, cancellationToken); + } + catch (Exception ex) + { + return Task.FromException(ex); } } @@ -127,13 +137,9 @@ public virtual async Task IsUpToDateAsync(ISet spaces, long timest cancellationToken.ThrowIfCancellationRequested(); if (spaces.Count == 0) return true; - cancellationToken.ThrowIfCancellationRequested(); - using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) - { - var lastUpdates = await (_updateTimestamps.GetManyAsync(spaces.ToArray(), cancellationToken)).ConfigureAwait(false); - return lastUpdates.All(lastUpdate => !IsOutdated(lastUpdate as long?, timestamp)); - } + var lastUpdates = await (_updateTimestamps.GetManyAsync(spaces.ToArray(), cancellationToken)).ConfigureAwait(false); + return lastUpdates.All(lastUpdate => !IsOutdated(lastUpdate as long?, timestamp)); } public virtual async Task AreUpToDateAsync(ISet[] spaces, long[] timestamps, CancellationToken cancellationToken) @@ -152,25 +158,21 @@ public virtual async Task AreUpToDateAsync(ISet[] spaces, long[] return ArrayHelper.Fill(true, spaces.Length); var keys = allSpaces.ToArray(); - cancellationToken.ThrowIfCancellationRequested(); - using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) - { - var index = 0; - var lastUpdatesBySpace = - (await (_updateTimestamps - .GetManyAsync(keys, cancellationToken)).ConfigureAwait(false)) - .ToDictionary(u => keys[index++], u => u as long?); - - var results = new bool[spaces.Length]; - for (var i = 0; i < spaces.Length; i++) - { - var timestamp = timestamps[i]; - results[i] = spaces[i].All(space => !IsOutdated(lastUpdatesBySpace[space], timestamp)); - } + var index = 0; + var lastUpdatesBySpace = + (await (_updateTimestamps + .GetManyAsync(keys, cancellationToken)).ConfigureAwait(false)) + .ToDictionary(u => keys[index++], u => u as long?); - return results; + var results = new bool[spaces.Length]; + for (var i = 0; i < spaces.Length; i++) + { + var timestamp = timestamps[i]; + results[i] = spaces[i].All(space => !IsOutdated(lastUpdatesBySpace[space], timestamp)); } + + return results; } } } diff --git a/src/NHibernate/Cache/UpdateTimestampsCache.cs b/src/NHibernate/Cache/UpdateTimestampsCache.cs index f6851f5ed44..6782f65972b 100644 --- a/src/NHibernate/Cache/UpdateTimestampsCache.cs +++ b/src/NHibernate/Cache/UpdateTimestampsCache.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; - using NHibernate.Cfg; using NHibernate.Util; @@ -19,7 +17,6 @@ public partial class UpdateTimestampsCache { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(UpdateTimestampsCache)); private readonly CacheBase _updateTimestamps; - private readonly AsyncReaderWriterLock _asyncReaderWriterLock = new AsyncReaderWriterLock(); public virtual void Clear() { @@ -60,13 +57,10 @@ public virtual void PreInvalidate(IReadOnlyCollection spaces) if (spaces.Count == 0) return; - using (_asyncReaderWriterLock.WriteLock()) - { - //TODO: to handle concurrent writes correctly, this should return a Lock to the client - var ts = _updateTimestamps.NextTimestamp() + _updateTimestamps.Timeout; - SetSpacesTimestamp(spaces, ts); - //TODO: return new Lock(ts); - } + //TODO: to handle concurrent writes correctly, this should return a Lock to the client + var ts = _updateTimestamps.NextTimestamp() + _updateTimestamps.Timeout; + SetSpacesTimestamp(spaces, ts); + //TODO: return new Lock(ts); } //Since v5.1 @@ -82,15 +76,12 @@ public virtual void Invalidate(IReadOnlyCollection spaces) if (spaces.Count == 0) return; - using (_asyncReaderWriterLock.WriteLock()) - { - //TODO: to handle concurrent writes correctly, the client should pass in a Lock - long ts = _updateTimestamps.NextTimestamp(); - //TODO: if lock.getTimestamp().equals(ts) - if (log.IsDebugEnabled()) - log.Debug("Invalidating spaces [{0}]", StringHelper.CollectionToString(spaces)); - SetSpacesTimestamp(spaces, ts); - } + //TODO: to handle concurrent writes correctly, the client should pass in a Lock + long ts = _updateTimestamps.NextTimestamp(); + //TODO: if lock.getTimestamp().equals(ts) + if (log.IsDebugEnabled()) + log.Debug("Invalidating spaces [{0}]", StringHelper.CollectionToString(spaces)); + SetSpacesTimestamp(spaces, ts); } private void SetSpacesTimestamp(IReadOnlyCollection spaces, long ts) @@ -105,11 +96,8 @@ public virtual bool IsUpToDate(ISet spaces, long timestamp /* H2.1 has L if (spaces.Count == 0) return true; - using (_asyncReaderWriterLock.ReadLock()) - { - var lastUpdates = _updateTimestamps.GetMany(spaces.ToArray()); - return lastUpdates.All(lastUpdate => !IsOutdated(lastUpdate as long?, timestamp)); - } + var lastUpdates = _updateTimestamps.GetMany(spaces.ToArray()); + return lastUpdates.All(lastUpdate => !IsOutdated(lastUpdate as long?, timestamp)); } public virtual bool[] AreUpToDate(ISet[] spaces, long[] timestamps) @@ -128,23 +116,20 @@ public virtual bool[] AreUpToDate(ISet[] spaces, long[] timestamps) var keys = allSpaces.ToArray(); - using (_asyncReaderWriterLock.ReadLock()) - { - var index = 0; - var lastUpdatesBySpace = - _updateTimestamps - .GetMany(keys) - .ToDictionary(u => keys[index++], u => u as long?); - - var results = new bool[spaces.Length]; - for (var i = 0; i < spaces.Length; i++) - { - var timestamp = timestamps[i]; - results[i] = spaces[i].All(space => !IsOutdated(lastUpdatesBySpace[space], timestamp)); - } + var index = 0; + var lastUpdatesBySpace = + _updateTimestamps + .GetMany(keys) + .ToDictionary(u => keys[index++], u => u as long?); - return results; + var results = new bool[spaces.Length]; + for (var i = 0; i < spaces.Length; i++) + { + var timestamp = timestamps[i]; + results[i] = spaces[i].All(space => !IsOutdated(lastUpdatesBySpace[space], timestamp)); } + + return results; } // Since v5.3 @@ -153,7 +138,6 @@ public virtual void Destroy() { // The cache is externally provided and may be shared. Destroying the cache is // not the responsibility of this class. - _asyncReaderWriterLock.Dispose(); } private static bool IsOutdated(long? lastUpdate, long timestamp)