Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrennan Conroy <brecon@microsoft.com>2022-08-30 02:38:25 +0300
committerBrennan Conroy <brecon@microsoft.com>2022-08-30 02:38:25 +0300
commitf265b5ab5df8e4e44fa3eaf75b1f2909a050351c (patch)
tree0172bfae1bb29a497ad76b773b7196ef67414e4a
parentdaed048f882dd2b19defa9647e4aefc4603e76f3 (diff)
-rw-r--r--src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs6
-rw-r--r--src/SignalR/server/Core/src/Internal/HubCallerClients.cs12
2 files changed, 12 insertions, 6 deletions
diff --git a/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs b/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs
index 508a04bb40..7e0b3f86bb 100644
--- a/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs
+++ b/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs
@@ -324,9 +324,9 @@ internal sealed partial class DefaultHubDispatcher<THub> : HubDispatcher<THub> w
if (hub.Clients is HubCallerClients hubCallerClients)
{
// Streaming invocations aren't involved with the semaphore.
- // Setting this to 0 avoids potential client result calls from the streaming hub method
+ // Setting the semaphore released flag avoids potential client result calls from the streaming hub method
// releasing the semaphore which would cause a SemaphoreFullException.
- hubCallerClients.ShouldReleaseSemaphore = 0;
+ hubCallerClients.TrySetSemaphoreReleased();
}
}
@@ -415,7 +415,7 @@ internal sealed partial class DefaultHubDispatcher<THub> : HubDispatcher<THub> w
{
if (hub?.Clients is HubCallerClients hubCallerClients)
{
- wasSemaphoreReleased = Interlocked.CompareExchange(ref hubCallerClients.ShouldReleaseSemaphore, 0, 1) == 0;
+ wasSemaphoreReleased = !hubCallerClients.TrySetSemaphoreReleased();
}
await CleanupInvocation(connection, hubMethodInvocationMessage, hubActivator, hub, scope);
}
diff --git a/src/SignalR/server/Core/src/Internal/HubCallerClients.cs b/src/SignalR/server/Core/src/Internal/HubCallerClients.cs
index 8e6ec0fa0d..15d2c03660 100644
--- a/src/SignalR/server/Core/src/Internal/HubCallerClients.cs
+++ b/src/SignalR/server/Core/src/Internal/HubCallerClients.cs
@@ -9,7 +9,7 @@ internal sealed class HubCallerClients : IHubCallerClients
private readonly IHubClients _hubClients;
internal readonly ChannelBasedSemaphore _parallelInvokes;
- internal int ShouldReleaseSemaphore = 1;
+ private int _shouldReleaseSemaphore = 1;
// Client results don't work in OnConnectedAsync
// This property is set by the hub dispatcher when those methods are being called
@@ -90,6 +90,12 @@ internal sealed class HubCallerClients : IHubCallerClients
return _hubClients.Users(userIds);
}
+ // false if semaphore is being released by another caller, true if you own releasing the semaphore
+ internal bool TrySetSemaphoreReleased()
+ {
+ return Interlocked.CompareExchange(ref _shouldReleaseSemaphore, 0, 1) == 1;
+ }
+
private sealed class NoInvokeSingleClientProxy : ISingleClientProxy
{
private readonly ISingleClientProxy _proxy;
@@ -125,9 +131,9 @@ internal sealed class HubCallerClients : IHubCallerClients
{
// Releases the Channel that is blocking pending invokes, which in turn can block the receive loop.
// Because we are waiting for a result from the client we need to let the receive loop run otherwise we'll be blocked forever
- var value = Interlocked.CompareExchange(ref _hubCallerClients.ShouldReleaseSemaphore, 0, 1);
+ var value = _hubCallerClients.TrySetSemaphoreReleased();
// Only release once, and we set ShouldReleaseSemaphore to 0 so the DefaultHubDispatcher knows not to call Release again
- if (value == 1)
+ if (value)
{
_hubCallerClients._parallelInvokes.Release();
}