Merge pull request #4199 from ryanpetris/livetv-locking

Fix stream performance when opening/closing new streams.
pull/4328/head
Anthony Lavado 4 years ago committed by GitHub
commit 8b419d9ea6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,7 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@ -43,7 +44,7 @@ namespace Emby.Server.Implementations.Library
private readonly ILocalizationManager _localizationManager; private readonly ILocalizationManager _localizationManager;
private readonly IApplicationPaths _appPaths; private readonly IApplicationPaths _appPaths;
private readonly Dictionary<string, ILiveStream> _openStreams = new Dictionary<string, ILiveStream>(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary<string, ILiveStream> _openStreams = new ConcurrentDictionary<string, ILiveStream>(StringComparer.OrdinalIgnoreCase);
private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1); private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1);
private IMediaSourceProvider[] _providers; private IMediaSourceProvider[] _providers;
@ -582,11 +583,7 @@ namespace Emby.Server.Implementations.Library
mediaSource.InferTotalBitrate(); mediaSource.InferTotalBitrate();
} }
public async Task<IDirectStreamProvider> GetDirectStreamProviderByUniqueId(string uniqueId, CancellationToken cancellationToken) public Task<IDirectStreamProvider> GetDirectStreamProviderByUniqueId(string uniqueId, CancellationToken cancellationToken)
{
await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{ {
var info = _openStreams.Values.FirstOrDefault(i => var info = _openStreams.Values.FirstOrDefault(i =>
{ {
@ -599,12 +596,7 @@ namespace Emby.Server.Implementations.Library
return false; return false;
}); });
return info as IDirectStreamProvider; return Task.FromResult(info as IDirectStreamProvider);
}
finally
{
_liveStreamSemaphore.Release();
}
} }
public async Task<LiveStreamResponse> OpenLiveStream(LiveStreamRequest request, CancellationToken cancellationToken) public async Task<LiveStreamResponse> OpenLiveStream(LiveStreamRequest request, CancellationToken cancellationToken)
@ -793,29 +785,20 @@ namespace Emby.Server.Implementations.Library
return new Tuple<MediaSourceInfo, IDirectStreamProvider>(info.MediaSource, info as IDirectStreamProvider); return new Tuple<MediaSourceInfo, IDirectStreamProvider>(info.MediaSource, info as IDirectStreamProvider);
} }
private async Task<ILiveStream> GetLiveStreamInfo(string id, CancellationToken cancellationToken) private Task<ILiveStream> GetLiveStreamInfo(string id, CancellationToken cancellationToken)
{ {
if (string.IsNullOrEmpty(id)) if (string.IsNullOrEmpty(id))
{ {
throw new ArgumentNullException(nameof(id)); throw new ArgumentNullException(nameof(id));
} }
await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
if (_openStreams.TryGetValue(id, out ILiveStream info)) if (_openStreams.TryGetValue(id, out ILiveStream info))
{ {
return info; return Task.FromResult(info);
} }
else else
{ {
throw new ResourceNotFoundException(); return Task.FromException<ILiveStream>(new ResourceNotFoundException());
}
}
finally
{
_liveStreamSemaphore.Release();
} }
} }
@ -844,7 +827,7 @@ namespace Emby.Server.Implementations.Library
if (liveStream.ConsumerCount <= 0) if (liveStream.ConsumerCount <= 0)
{ {
_openStreams.Remove(id); _openStreams.TryRemove(id, out _);
_logger.LogInformation("Closing live stream {0}", id); _logger.LogInformation("Closing live stream {0}", id);

Loading…
Cancel
Save