aboutsummaryrefslogtreecommitdiff
path: root/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-09-27 22:42:40 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2023-09-27 22:42:40 -0400
commitd6b453a937a344fcc3d22cdc7e7a9f7d5888e424 (patch)
treec2842144f755472a32fc8ad14172b9d1699ff6d7 /libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs
parent6138eb6ba9eded16044a770bd5cf08d431375802 (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.cs92
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/>