diff --git a/cs/src/core/ClientSession/BasicContext.cs b/cs/src/core/ClientSession/BasicContext.cs new file mode 100644 index 000000000..7e496af18 --- /dev/null +++ b/cs/src/core/ClientSession/BasicContext.cs @@ -0,0 +1,228 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; + +namespace FASTER.core +{ + /// + /// Basic Faster Context implementation. + /// + public readonly struct BasicContext : IFasterContext + where Functions : IFunctions + { + readonly ClientSession clientSession; + + internal BasicContext(ClientSession clientSession) + { + this.clientSession = clientSession; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnsafeResumeThread() + => clientSession.UnsafeResumeThread(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnsafeResumeThread(out int resumeEpoch) + => clientSession.UnsafeResumeThread(out resumeEpoch); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnsafeSuspendThread() + => clientSession.UnsafeSuspendThread(); + + #region IFasterContext + + /// + public bool CompletePending(bool wait = false, bool spinWaitForCommit = false) + => clientSession.CompletePending(wait, spinWaitForCommit); + + /// + public bool CompletePendingWithOutputs(out CompletedOutputIterator completedOutputs, bool wait = false, bool spinWaitForCommit = false) + => clientSession.CompletePendingWithOutputs(out completedOutputs, wait, spinWaitForCommit); + + /// + public ValueTask CompletePendingAsync(bool waitForCommit = false, CancellationToken token = default) + => clientSession.CompletePendingAsync(waitForCommit, token); + + /// + public ValueTask> CompletePendingWithOutputsAsync(bool waitForCommit = false, CancellationToken token = default) + => clientSession.CompletePendingWithOutputsAsync(waitForCommit, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Read(ref Key key, ref Input input, ref Output output, Context userContext = default, long serialNo = 0) + => clientSession.Read(ref key, ref input, ref output, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Read(Key key, Input input, out Output output, Context userContext = default, long serialNo = 0) + => clientSession.Read(key, input, out output, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Read(ref Key key, ref Output output, Context userContext = default, long serialNo = 0) + => clientSession.Read(ref key, ref output, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Read(Key key, out Output output, Context userContext = default, long serialNo = 0) + => clientSession.Read(key, out output, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public (Status status, Output output) Read(Key key, Context userContext = default, long serialNo = 0) + => clientSession.Read(key, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Read(ref Key key, ref Input input, ref Output output, ref ReadOptions readOptions, out RecordMetadata recordMetadata, Context userContext = default, long serialNo = 0) + => clientSession.Read(ref key, ref input, ref output, ref readOptions, out recordMetadata, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status ReadAtAddress(ref Input input, ref Output output, ref ReadOptions readOptions, Context userContext = default, long serialNo = 0) + => clientSession.ReadAtAddress(ref input, ref output, ref readOptions, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.ReadAsyncResult> ReadAsync(ref Key key, ref Input input, Context userContext = default, long serialNo = 0, CancellationToken cancellationToken = default) + => clientSession.ReadAsync(ref key, ref input, userContext, serialNo, cancellationToken); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.ReadAsyncResult> ReadAsync(Key key, Input input, Context context = default, long serialNo = 0, CancellationToken token = default) + => clientSession.ReadAsync(key, input, context, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.ReadAsyncResult> ReadAsync(ref Key key, Context userContext = default, long serialNo = 0, CancellationToken token = default) + => clientSession.ReadAsync(ref key, userContext, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.ReadAsyncResult> ReadAsync(Key key, Context context = default, long serialNo = 0, CancellationToken token = default) + => clientSession.ReadAsync(key, context, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.ReadAsyncResult> ReadAsync(ref Key key, ref Input input, ref ReadOptions readOptions, Context userContext = default, long serialNo = 0, CancellationToken cancellationToken = default) + => clientSession.ReadAsync(ref key, ref input, ref readOptions, userContext, serialNo, cancellationToken); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.ReadAsyncResult> ReadAtAddressAsync(ref Input input, ref ReadOptions readOptions, Context userContext = default, long serialNo = 0, CancellationToken cancellationToken = default) + => clientSession.ReadAtAddressAsync(ref input, ref readOptions, userContext, serialNo, cancellationToken); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Upsert(ref Key key, ref Value desiredValue, Context userContext = default, long serialNo = 0) + => clientSession.Upsert(ref key, ref desiredValue, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Upsert(ref Key key, ref Input input, ref Value desiredValue, ref Output output, Context userContext = default, long serialNo = 0) + => clientSession.Upsert(ref key, ref input, ref desiredValue, ref output, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Upsert(ref Key key, ref Input input, ref Value desiredValue, ref Output output, out RecordMetadata recordMetadata, Context userContext = default, long serialNo = 0) + => clientSession.Upsert(ref key, ref input, ref desiredValue, ref output, out recordMetadata, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Upsert(Key key, Value desiredValue, Context userContext = default, long serialNo = 0) + => clientSession.Upsert(key, desiredValue, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Upsert(Key key, Input input, Value desiredValue, ref Output output, Context userContext = default, long serialNo = 0) + => clientSession.Upsert(key, input, desiredValue, ref output, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.UpsertAsyncResult> UpsertAsync(ref Key key, ref Value desiredValue, Context userContext = default, long serialNo = 0, CancellationToken token = default) + => clientSession.UpsertAsync(ref key, ref desiredValue, userContext, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.UpsertAsyncResult> UpsertAsync(ref Key key, ref Input input, ref Value desiredValue, Context userContext = default, long serialNo = 0, CancellationToken token = default) + => clientSession.UpsertAsync(ref key, ref input, ref desiredValue, userContext, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.UpsertAsyncResult> UpsertAsync(Key key, Value desiredValue, Context userContext = default, long serialNo = 0, CancellationToken token = default) + => clientSession.UpsertAsync(key, desiredValue, userContext, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.UpsertAsyncResult> UpsertAsync(Key key, Input input, Value desiredValue, Context userContext = default, long serialNo = 0, CancellationToken token = default) + => clientSession.UpsertAsync(key, input, desiredValue, userContext, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status RMW(ref Key key, ref Input input, ref Output output, Context userContext = default, long serialNo = 0) + => clientSession.RMW(ref key, ref input, ref output, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status RMW(ref Key key, ref Input input, ref Output output, out RecordMetadata recordMetadata, Context userContext = default, long serialNo = 0) + => clientSession.RMW(ref key, ref input, ref output, out recordMetadata, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status RMW(Key key, Input input, out Output output, Context userContext = default, long serialNo = 0) + => clientSession.RMW(key, input, out output, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status RMW(ref Key key, ref Input input, Context userContext = default, long serialNo = 0) + => clientSession.RMW(ref key, ref input, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status RMW(Key key, Input input, Context userContext = default, long serialNo = 0) + => clientSession.RMW(key, input, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.RmwAsyncResult> RMWAsync(ref Key key, ref Input input, Context context = default, long serialNo = 0, CancellationToken token = default) + => clientSession.RMWAsync(ref key, ref input, context, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.RmwAsyncResult> RMWAsync(Key key, Input input, Context context = default, long serialNo = 0, CancellationToken token = default) + => clientSession.RMWAsync(key, input, context, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Delete(ref Key key, Context userContext = default, long serialNo = 0) + => clientSession.Delete(ref key, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Status Delete(Key key, Context userContext = default, long serialNo = 0) + => clientSession.Delete(key, userContext, serialNo); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.DeleteAsyncResult> DeleteAsync(ref Key key, Context userContext = default, long serialNo = 0, CancellationToken token = default) + => clientSession.DeleteAsync(ref key, userContext, serialNo, token); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask.DeleteAsyncResult> DeleteAsync(Key key, Context userContext = default, long serialNo = 0, CancellationToken token = default) + => clientSession.DeleteAsync(key, userContext, serialNo, token); + + /// + public void Refresh() + => clientSession.Refresh(); + + #endregion IFasterContext + } +} diff --git a/cs/src/core/ClientSession/ClientSession.cs b/cs/src/core/ClientSession/ClientSession.cs index 4b79664e6..b117954c7 100644 --- a/cs/src/core/ClientSession/ClientSession.cs +++ b/cs/src/core/ClientSession/ClientSession.cs @@ -37,13 +37,51 @@ public sealed class ClientSession UnsafeContext uContext; LockableUnsafeContext luContext; - LockableContext lContext; + readonly LockableContext lContext; + readonly BasicContext bContext; internal const string NotAsyncSessionErr = "Session does not support async operations"; readonly ILoggerFactory loggerFactory; readonly ILogger logger; + internal ulong TotalLockCount => sharedLockCount + exclusiveLockCount; + internal ulong sharedLockCount; + internal ulong exclusiveLockCount; + + bool isAcquired; + + internal void Acquire() + { + CheckNotAcquired(); + fht.IncrementNumLockingSessions(); + isAcquired = true; + } + + internal void Release() + { + CheckAcquired(); + isAcquired = false; + fht.DecrementNumLockingSessions(); + } + + internal void CheckAcquired() + { + if (!isAcquired) + throw new FasterException("Method call on not-acquired Context"); + } + + void CheckNotAcquired() + { + if (isAcquired) + throw new FasterException("Method call on acquired Context"); + } + + /// + /// Local current epoch + /// + public int LocalCurrentEpoch => fht.epoch.LocalCurrentEpoch; + internal ClientSession( FasterKV fht, FasterKV.FasterExecutionContext ctx, @@ -51,8 +89,11 @@ internal ClientSession( SessionVariableLengthStructSettings sessionVariableLengthStructSettings, ILoggerFactory loggerFactory = null) { + this.lContext = new(this); + this.bContext = new(this); + this.loggerFactory = loggerFactory; - this.logger = loggerFactory?.CreateLogger($"ClientSession-{GetHashCode().ToString("X8")}"); + this.logger = loggerFactory?.CreateLogger($"ClientSession-{GetHashCode():X8}"); this.fht = fht; this.ctx = ctx; this.functions = functions; @@ -72,7 +113,7 @@ internal ClientSession( } else { - if (!(fht.hlog is VariableLengthBlittableAllocator)) + if (fht.hlog is not VariableLengthBlittableAllocator) logger?.LogWarning("Warning: Session param of variableLengthStruct provided for non-varlen allocator"); } @@ -101,7 +142,7 @@ internal ClientSession( private void UpdateVarlen(ref IVariableLengthStruct variableLengthStruct) { - if (!(fht.hlog is VariableLengthBlittableAllocator)) + if (fht.hlog is not VariableLengthBlittableAllocator) return; if (typeof(Value) == typeof(SpanByte) && typeof(Input) == typeof(SpanByte)) @@ -181,14 +222,14 @@ public LockableUnsafeContext GetL } /// - /// Return a new interface to Faster operations that supports manual locking. + /// Return a session wrapper that supports manual locking. /// - public LockableContext GetLockableContext() - { - this.lContext ??= new(this); - this.lContext.Acquire(); - return this.lContext; - } + public LockableContext LockableContext => lContext; + + /// + /// Return a session wrapper struct that passes through to client session + /// + public BasicContext BasicContext => bContext; #region IFasterContext /// diff --git a/cs/src/core/ClientSession/LockableContext.cs b/cs/src/core/ClientSession/LockableContext.cs index d40a1a47c..6eeda711b 100644 --- a/cs/src/core/ClientSession/LockableContext.cs +++ b/cs/src/core/ClientSession/LockableContext.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading; @@ -12,23 +11,11 @@ namespace FASTER.core /// /// Faster Context implementation that allows manual control of record locking and epoch management. For advanced use only. /// - public sealed class LockableContext : IFasterContext, ILockableContext, IDisposable + public readonly struct LockableContext : IFasterContext, ILockableContext where Functions : IFunctions { readonly ClientSession clientSession; - - internal readonly InternalFasterSession FasterSession; - bool isAcquired; - - ulong TotalLockCount => sharedLockCount + exclusiveLockCount; - internal ulong sharedLockCount; - internal ulong exclusiveLockCount; - - void CheckAcquired() - { - if (!isAcquired) - throw new FasterException("Method call on unacquired LockableContext"); - } + readonly InternalFasterSession FasterSession; internal LockableContext(ClientSession clientSession) { @@ -40,7 +27,7 @@ internal LockableContext(ClientSession clientSession.fht.epoch.LocalCurrentEpoch; #region Acquire and Dispose - internal void Acquire() + + /// + /// Acquire a lockable context + /// + public void Acquire() { - this.clientSession.fht.IncrementNumLockingSessions(); - if (this.isAcquired) - throw new FasterException("Trying to acquire an already-acquired LockableContext"); - this.isAcquired = true; + clientSession.Acquire(); } /// - /// Does not actually dispose of anything; asserts the epoch has been suspended + /// Release a lockable context; does not actually dispose of anything /// - public void Dispose() + public void Release() { - CheckAcquired(); if (clientSession.fht.epoch.ThisInstanceProtected()) - throw new FasterException("Disposing LockableContext with a protected epoch; must call UnsafeSuspendThread"); - if (TotalLockCount > 0) - throw new FasterException($"Disposing LockableContext with locks held: {sharedLockCount} shared locks, {exclusiveLockCount} exclusive locks"); - this.isAcquired = false; - this.clientSession.fht.DecrementNumLockingSessions(); + throw new FasterException("Releasing LockableContext with a protected epoch; must call UnsafeSuspendThread"); + if (clientSession.TotalLockCount > 0) + throw new FasterException($"Releasing LockableContext with locks held: {clientSession.sharedLockCount} shared locks, {clientSession.exclusiveLockCount} exclusive locks"); + clientSession.Release(); } #endregion Acquire and Dispose @@ -95,7 +81,7 @@ public void Dispose() /// public unsafe void Lock(ref Key key, LockType lockType) { - CheckAcquired(); + clientSession.CheckAcquired(); Debug.Assert(!clientSession.fht.epoch.ThisInstanceProtected()); clientSession.UnsafeResumeThread(); try @@ -110,9 +96,9 @@ public unsafe void Lock(ref Key key, LockType lockType) Debug.Assert(status == OperationStatus.SUCCESS); if (lockType == LockType.Exclusive) - ++this.exclusiveLockCount; + ++clientSession.exclusiveLockCount; else - ++this.sharedLockCount; + ++clientSession.sharedLockCount; } finally { @@ -126,7 +112,7 @@ public unsafe void Lock(ref Key key, LockType lockType) /// public void Unlock(ref Key key, LockType lockType) { - CheckAcquired(); + clientSession.CheckAcquired(); Debug.Assert(!clientSession.fht.epoch.ThisInstanceProtected()); clientSession.UnsafeResumeThread(); try @@ -141,9 +127,9 @@ public void Unlock(ref Key key, LockType lockType) Debug.Assert(status == OperationStatus.SUCCESS); if (lockType == LockType.Exclusive) - --this.exclusiveLockCount; + --clientSession.exclusiveLockCount; else - --this.sharedLockCount; + --clientSession.sharedLockCount; } finally { @@ -157,7 +143,7 @@ public void Unlock(ref Key key, LockType lockType) /// public (bool exclusive, byte shared) IsLocked(ref Key key) { - CheckAcquired(); + clientSession.CheckAcquired(); Debug.Assert(!clientSession.fht.epoch.ThisInstanceProtected()); clientSession.UnsafeResumeThread(); try @@ -185,7 +171,7 @@ public void Unlock(ref Key key, LockType lockType) /// /// The session id of FasterSession /// - public int sessionID { get { return clientSession.ctx.sessionID; } } + public int SessionID { get { return clientSession.ctx.sessionID; } } #endregion Key Locking diff --git a/cs/src/core/ClientSession/LockableUnsafeContext.cs b/cs/src/core/ClientSession/LockableUnsafeContext.cs index 17d0d7fda..054f04dc6 100644 --- a/cs/src/core/ClientSession/LockableUnsafeContext.cs +++ b/cs/src/core/ClientSession/LockableUnsafeContext.cs @@ -16,19 +16,7 @@ public sealed class LockableUnsafeContext { readonly ClientSession clientSession; - internal readonly InternalFasterSession FasterSession; - bool isAcquired; - - ulong TotalLockCount => sharedLockCount + exclusiveLockCount; - internal ulong sharedLockCount; - internal ulong exclusiveLockCount; - - void CheckAcquired() - { - if (!isAcquired) - throw new FasterException("Method call on not-acquired LockableUnsafeContext"); - } internal LockableUnsafeContext(ClientSession clientSession) { @@ -40,7 +28,7 @@ internal LockableUnsafeContext(ClientSession @@ -79,10 +65,9 @@ public void Dispose() { if (clientSession.fht.epoch.ThisInstanceProtected()) throw new FasterException("Disposing LockableUnsafeContext with a protected epoch; must call UnsafeSuspendThread"); - if (TotalLockCount > 0) - throw new FasterException($"Disposing LockableUnsafeContext with locks held: {sharedLockCount} shared locks, {exclusiveLockCount} exclusive locks"); - this.isAcquired = false; - this.clientSession.fht.DecrementNumLockingSessions(); + if (clientSession.TotalLockCount > 0) + throw new FasterException($"Disposing LockableUnsafeContext with locks held: {clientSession.sharedLockCount} shared locks, {clientSession.exclusiveLockCount} exclusive locks"); + clientSession.Release(); } #endregion Acquire and Dispose @@ -91,7 +76,7 @@ public void Dispose() /// public unsafe void Lock(ref Key key, LockType lockType) { - CheckAcquired(); + clientSession.CheckAcquired(); Debug.Assert(clientSession.fht.epoch.ThisInstanceProtected(), "Epoch protection required for Lock()"); LockOperation lockOp = new(LockOperationType.Lock, lockType); @@ -104,9 +89,9 @@ public unsafe void Lock(ref Key key, LockType lockType) Debug.Assert(status == OperationStatus.SUCCESS); if (lockType == LockType.Exclusive) - ++this.exclusiveLockCount; + ++clientSession.exclusiveLockCount; else - ++this.sharedLockCount; + ++clientSession.sharedLockCount; } /// @@ -115,7 +100,7 @@ public unsafe void Lock(ref Key key, LockType lockType) /// public void Unlock(ref Key key, LockType lockType) { - CheckAcquired(); + clientSession.CheckAcquired(); Debug.Assert(clientSession.fht.epoch.ThisInstanceProtected(), "Epoch protection required for Unlock()"); LockOperation lockOp = new(LockOperationType.Unlock, lockType); @@ -128,9 +113,9 @@ public void Unlock(ref Key key, LockType lockType) Debug.Assert(status == OperationStatus.SUCCESS); if (lockType == LockType.Exclusive) - --this.exclusiveLockCount; + --clientSession.exclusiveLockCount; else - --this.sharedLockCount; + --clientSession.sharedLockCount; } /// @@ -139,7 +124,7 @@ public void Unlock(ref Key key, LockType lockType) /// public (bool exclusive, byte shared) IsLocked(ref Key key) { - CheckAcquired(); + clientSession.CheckAcquired(); Debug.Assert(clientSession.fht.epoch.ThisInstanceProtected(), "Epoch protection required for IsLocked()"); LockOperation lockOp = new(LockOperationType.IsLocked, LockType.None); @@ -160,7 +145,7 @@ public void Unlock(ref Key key, LockType lockType) /// /// The session id of FasterSession /// - public int sessionID { get { return clientSession.ctx.sessionID; } } + public int SessionID { get { return clientSession.ctx.sessionID; } } #endregion Key Locking diff --git a/cs/src/core/FasterLog/FasterLogIterator.cs b/cs/src/core/FasterLog/FasterLogIterator.cs index 115a2a5f0..4721f3104 100644 --- a/cs/src/core/FasterLog/FasterLogIterator.cs +++ b/cs/src/core/FasterLog/FasterLogIterator.cs @@ -551,10 +551,11 @@ public override void Dispose() if (name != null) fasterLog.PersistedIterators.TryRemove(name, out _); + if (Interlocked.Decrement(ref fasterLog.logRefCount) == 0) + fasterLog.TrueDispose(); + disposed = true; } - if (Interlocked.Decrement(ref fasterLog.logRefCount) == 0) - fasterLog.TrueDispose(); } internal override void AsyncReadPagesFromDeviceToFrame(long readPageStart, int numPages, long untilAddress, TContext context, out CountdownEvent completed, long devicePageOffset = 0, IDevice device = null, IDevice objectLogDevice = null, CancellationTokenSource cts = null) diff --git a/cs/test/LockableUnsafeContextTests.cs b/cs/test/LockableUnsafeContextTests.cs index 56637506c..16b5c9ebe 100644 --- a/cs/test/LockableUnsafeContextTests.cs +++ b/cs/test/LockableUnsafeContextTests.cs @@ -145,21 +145,21 @@ void PrepareRecordLocation(FlushMode recordLocation) this.fht.Log.FlushAndEvict(wait: true); } - static void ClearCountsOnError(LockableUnsafeContext luContext) + static void ClearCountsOnError(ClientSession luContext) { // If we already have an exception, clear these counts so "Run" will not report them spuriously. luContext.sharedLockCount = 0; luContext.exclusiveLockCount = 0; } - static void ClearCountsOnError(LockableUnsafeContext> luContext) + static void ClearCountsOnError(ClientSession> luContext) { // If we already have an exception, clear these counts so "Run" will not report them spuriously. luContext.sharedLockCount = 0; luContext.exclusiveLockCount = 0; } - static void ClearCountsOnError(LockableUnsafeContext> luContext) + static void ClearCountsOnError(ClientSession> luContext) { // If we already have an exception, clear these counts so "Run" will not report them spuriously. luContext.sharedLockCount = 0; @@ -409,7 +409,7 @@ public void InMemorySimpleLockTxnTest([Values] ResultLockTarget resultLockTarget } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -496,7 +496,7 @@ public void InMemoryLongLockTest([Values] ResultLockTarget resultLockTarget, [Va } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -554,7 +554,7 @@ public void InMemoryDeleteTest([Values] ResultLockTarget resultLockTarget, [Valu } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -705,7 +705,7 @@ public void TransferFromLockTableToCTTTest() } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -757,7 +757,7 @@ public void TransferFromLockTableToUpsertTest([Values] ChainTests.RecordRegion r } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -799,7 +799,7 @@ public void TransferFromLockTableToRMWTest([Values] ChainTests.RecordRegion reco } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -846,7 +846,7 @@ public void TransferFromLockTableToDeleteTest([Values] ChainTests.RecordRegion r } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -894,7 +894,7 @@ public void LockAndUnlockInLockTableOnlyTest() } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -947,7 +947,7 @@ public void TransferFromReadOnlyToUpdateRecordTest([Values] UpdateOp updateOp) } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -1036,7 +1036,7 @@ void unlockKey(int key) } catch (Exception) { - ClearCountsOnError(lockLuContext); + ClearCountsOnError(lockSession); throw; } finally @@ -1056,7 +1056,7 @@ void locker(int key) } catch (Exception) { - ClearCountsOnError(lockLuContext); + ClearCountsOnError(lockSession); throw; } finally @@ -1086,7 +1086,7 @@ void updater(int key) } catch (Exception) { - ClearCountsOnError(updateLuContext); + ClearCountsOnError(updateSession); throw; } finally @@ -1131,7 +1131,7 @@ public void MultiSharedLockTest() } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -1202,7 +1202,7 @@ public void EvictFromMainLogToLockTableTest() } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -1243,7 +1243,7 @@ public async ValueTask CheckpointRecoverTest([Values] CheckpointType checkpointT } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -1270,7 +1270,7 @@ public async ValueTask CheckpointRecoverTest([Values] CheckpointType checkpointT } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -1302,7 +1302,7 @@ public async ValueTask CheckpointRecoverTest([Values] CheckpointType checkpointT } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -1382,7 +1382,7 @@ async static Task PrimaryWriter(FasterKV primaryStore, SyncMode sync } catch (Exception) { - ClearCountsOnError(luc1); + ClearCountsOnError(s1); throw; } finally @@ -1406,7 +1406,7 @@ async static Task PrimaryWriter(FasterKV primaryStore, SyncMode sync } catch (Exception) { - ClearCountsOnError(luc1); + ClearCountsOnError(s1); throw; } finally @@ -1462,7 +1462,7 @@ async static Task SecondaryReader(FasterKV secondaryStore, SyncMode } catch (Exception) { - ClearCountsOnError(luc1); + ClearCountsOnError(s1); throw; } finally diff --git a/cs/test/ReadCacheChainTests.cs b/cs/test/ReadCacheChainTests.cs index 840898941..a33699e50 100644 --- a/cs/test/ReadCacheChainTests.cs +++ b/cs/test/ReadCacheChainTests.cs @@ -227,7 +227,7 @@ void VerifySplicedInKey(int expectedKey) Assert.AreEqual(expectedKey, storedKey); } - static void ClearCountsOnError(LockableUnsafeContext> luContext) + static void ClearCountsOnError(ClientSession> luContext) { // If we already have an exception, clear these counts so "Run" will not report them spuriously. luContext.sharedLockCount = 0; @@ -531,7 +531,7 @@ public void EvictFromReadCacheToLockTableTest() } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -607,7 +607,7 @@ public void TransferFromLockTableToReadCacheTest() } catch (Exception) { - ClearCountsOnError(luContext); + ClearCountsOnError(session); throw; } finally @@ -718,7 +718,7 @@ unsafe void PopulateAndEvict() fht.Log.FlushAndEvict(true); } - static void ClearCountsOnError(LockableUnsafeContext> luContext) + static void ClearCountsOnError(ClientSession> luContext) { // If we already have an exception, clear these counts so "Run" will not report them spuriously. luContext.sharedLockCount = 0; @@ -903,7 +903,7 @@ unsafe void PopulateAndEvict() fht.Log.FlushAndEvict(true); } - static void ClearCountsOnError(LockableUnsafeContext> luContext) + static void ClearCountsOnError(ClientSession> luContext) { // If we already have an exception, clear these counts so "Run" will not report them spuriously. luContext.sharedLockCount = 0;