mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
fix: use a reentrant lock when accessing active connections (#11256)
This commit is contained in:
parent
fe88a484d1
commit
4201079b34
@ -48,7 +48,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
|
|
||||||
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
|
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
using var connection = new WebSocketConnection(
|
var connection = new WebSocketConnection(
|
||||||
_loggerFactory.CreateLogger<WebSocketConnection>(),
|
_loggerFactory.CreateLogger<WebSocketConnection>(),
|
||||||
webSocket,
|
webSocket,
|
||||||
authorizationInfo,
|
authorizationInfo,
|
||||||
@ -56,17 +56,19 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
{
|
{
|
||||||
OnReceive = ProcessWebSocketMessageReceived
|
OnReceive = ProcessWebSocketMessageReceived
|
||||||
};
|
};
|
||||||
|
await using (connection.ConfigureAwait(false))
|
||||||
var tasks = new Task[_webSocketListeners.Length];
|
|
||||||
for (var i = 0; i < _webSocketListeners.Length; ++i)
|
|
||||||
{
|
{
|
||||||
tasks[i] = _webSocketListeners[i].ProcessWebSocketConnectedAsync(connection, context);
|
var tasks = new Task[_webSocketListeners.Length];
|
||||||
|
for (var i = 0; i < _webSocketListeners.Length; ++i)
|
||||||
|
{
|
||||||
|
tasks[i] = _webSocketListeners[i].ProcessWebSocketConnectedAsync(connection, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
|
|
||||||
|
await connection.ReceiveAsync().ConfigureAwait(false);
|
||||||
|
_logger.LogInformation("WS {IP} closed", context.Connection.RemoteIpAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
|
||||||
|
|
||||||
await connection.ReceiveAsync().ConfigureAwait(false);
|
|
||||||
_logger.LogInformation("WS {IP} closed", context.Connection.RemoteIpAddress);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex) // Otherwise ASP.Net will ignore the exception
|
catch (Exception ex) // Otherwise ASP.Net will ignore the exception
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Net
|
|||||||
SingleWriter = false
|
SingleWriter = false
|
||||||
});
|
});
|
||||||
|
|
||||||
private readonly SemaphoreSlim _lock = new(1, 1);
|
private readonly object _activeConnectionsLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _active connections.
|
/// The _active connections.
|
||||||
@ -126,15 +126,10 @@ namespace MediaBrowser.Controller.Net
|
|||||||
InitialDelayMs = dueTimeMs
|
InitialDelayMs = dueTimeMs
|
||||||
};
|
};
|
||||||
|
|
||||||
_lock.Wait();
|
lock (_activeConnectionsLock)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
_activeConnections.Add((message.Connection, cancellationTokenSource, state));
|
_activeConnections.Add((message.Connection, cancellationTokenSource, state));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
_lock.Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SendData(bool force)
|
protected void SendData(bool force)
|
||||||
@ -153,8 +148,7 @@ namespace MediaBrowser.Controller.Net
|
|||||||
(IWebSocketConnection Connection, CancellationTokenSource CancellationTokenSource, TStateType State)[] tuples;
|
(IWebSocketConnection Connection, CancellationTokenSource CancellationTokenSource, TStateType State)[] tuples;
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
await _lock.WaitAsync().ConfigureAwait(false);
|
lock (_activeConnectionsLock)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (_activeConnections.Count == 0)
|
if (_activeConnections.Count == 0)
|
||||||
{
|
{
|
||||||
@ -174,10 +168,6 @@ namespace MediaBrowser.Controller.Net
|
|||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
_lock.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tuples.Length == 0)
|
if (tuples.Length == 0)
|
||||||
{
|
{
|
||||||
@ -240,8 +230,7 @@ namespace MediaBrowser.Controller.Net
|
|||||||
/// <param name="message">The message.</param>
|
/// <param name="message">The message.</param>
|
||||||
private void Stop(WebSocketMessageInfo message)
|
private void Stop(WebSocketMessageInfo message)
|
||||||
{
|
{
|
||||||
_lock.Wait();
|
lock (_activeConnectionsLock)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var connection = _activeConnections.FirstOrDefault(c => c.Connection == message.Connection);
|
var connection = _activeConnections.FirstOrDefault(c => c.Connection == message.Connection);
|
||||||
|
|
||||||
@ -250,10 +239,6 @@ namespace MediaBrowser.Controller.Net
|
|||||||
DisposeConnection(connection);
|
DisposeConnection(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
_lock.Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -283,15 +268,10 @@ namespace MediaBrowser.Controller.Net
|
|||||||
Logger.LogError(ex, "Error disposing websocket");
|
Logger.LogError(ex, "Error disposing websocket");
|
||||||
}
|
}
|
||||||
|
|
||||||
_lock.Wait();
|
lock (_activeConnectionsLock)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
_activeConnections.Remove(connection);
|
_activeConnections.Remove(connection);
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
_lock.Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual async ValueTask DisposeAsyncCore()
|
protected virtual async ValueTask DisposeAsyncCore()
|
||||||
@ -306,18 +286,13 @@ namespace MediaBrowser.Controller.Net
|
|||||||
Logger.LogError(ex, "Disposing the message consumer failed");
|
Logger.LogError(ex, "Disposing the message consumer failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
await _lock.WaitAsync().ConfigureAwait(false);
|
lock (_activeConnectionsLock)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
foreach (var connection in _activeConnections.ToArray())
|
foreach (var connection in _activeConnections.ToArray())
|
||||||
{
|
{
|
||||||
DisposeConnection(connection);
|
DisposeConnection(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
_lock.Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user