diff options
author | vnugent <public@vaughnnugent.com> | 2023-09-27 22:42:40 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-09-27 22:42:40 -0400 |
commit | d6b453a937a344fcc3d22cdc7e7a9f7d5888e424 (patch) | |
tree | c2842144f755472a32fc8ad14172b9d1699ff6d7 /libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs | |
parent | 6138eb6ba9eded16044a770bd5cf08d431375802 (diff) |
package and license file updates
Diffstat (limited to 'libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs')
-rw-r--r-- | libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs | 92 |
1 files changed, 59 insertions, 33 deletions
diff --git a/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs b/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs index 32dcc34..18ea99e 100644 --- a/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs +++ b/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs @@ -55,13 +55,13 @@ namespace VNLib.Plugins.Sessions.Cache.Client */ private readonly Dictionary<string, WaitEntry> _waitTable; - + /// <summary> /// Initializes a new <see cref="SessionSerializer{TSession}"/> /// </summary> /// <param name="poolCapacity">The maximum number of wait entry instances to hold in memory cache</param> - public SessionSerializer(int poolCapacity):base(poolCapacity, 0, null) + public SessionSerializer(int poolCapacity) : base(poolCapacity, 0, null) { //Session-ids are security senstive, we must use ordinal(binary) string comparison _waitTable = new Dictionary<string, WaitEntry>(poolCapacity, StringComparer.Ordinal); @@ -86,23 +86,48 @@ namespace VNLib.Plugins.Sessions.Cache.Client cancellation.ThrowIfCancellationRequested(); WaitEnterToken token; + WaitEntry? wait; - lock (StoreLock) + if (cancellation.CanBeCanceled) { - //See if the entry already exists, otherwise get a new wait entry - if (!_waitTable.TryGetValue(moniker.SessionID, out WaitEntry? wait)) + lock (StoreLock) { - GetWaitEntry(ref wait, moniker); + //See if the entry already exists, otherwise get a new wait entry + if (!_waitTable.TryGetValue(moniker.SessionID, out wait)) + { + GetWaitEntry(ref wait, moniker); - //Add entry to store - _waitTable[moniker.SessionID] = wait; + //Add entry to store + _waitTable[moniker.SessionID] = wait; + } + + //Get waiter before leaving lock + wait.ScheduleWait(cancellation, out token); } - //Get waiter before leaving lock - wait.GetWaiter(out token); + //Enter wait and setup cancellation continuation + return EnterCancellableWait(in token, wait); } + else + { + lock (StoreLock) + { + //See if the entry already exists, otherwise get a new wait entry + if (!WaitTable.TryGetValue(moniker, out wait)) + { + GetWaitEntry(ref wait, moniker); + + //Add entry to store + WaitTable[moniker] = wait; + } + + //Get waiter before leaving lock + wait.ScheduleWait(out token); + } - return token.EnterWaitAsync(cancellation); + //Enter the waiter without any cancellation support + return token.EnterWaitAsync(); + } } ///<inheritdoc/> @@ -110,31 +135,32 @@ namespace VNLib.Plugins.Sessions.Cache.Client { WaitReleaseToken releaser; - lock (StoreLock) + do { - WaitEntry entry = _waitTable[moniker.SessionID]; - - //Call release while holding store lock - if(entry.Release(out releaser) == 0) + lock (StoreLock) { - //No more waiters - _waitTable.Remove(moniker.SessionID); - - /* - * We must release the semaphore before returning to pool, - * its safe because there are no more waiters - */ - releaser.Release(); - - ReturnEntry(entry); - - //already released - releaser = default; - } - } + WaitEntry entry = _waitTable[moniker.SessionID]; - //Release sem outside of lock - releaser.Release(); + //Call release while holding store lock + if (entry.ExitWait(out releaser) == 0) + { + //No more waiters + _waitTable.Remove(moniker.SessionID); + + /* + * We must release the semaphore before returning to pool, + * its safe because there are no more waiters + */ + releaser.Release(); + + ReturnEntry(entry); + + //already released + releaser = default; + } + } + //See base class for why we need to loop + } while (!releaser.Release()); } ///<inheritdoc/> |