2
0
Эх сурвалжийг харах

Don't take a lock if there's no intention to manipulate the list of open streams. Instead, use a ConcurrentDictionary so that, in those situations, thread-safe access to the dictionary is ensured.

Ryan Petris 4 жил өмнө
parent
commit
4db5700e18

+ 17 - 34
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -1,6 +1,7 @@
 #pragma warning disable CS1591
 
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
@@ -43,7 +44,7 @@ namespace Emby.Server.Implementations.Library
         private readonly ILocalizationManager _localizationManager;
         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 IMediaSourceProvider[] _providers;
@@ -582,29 +583,20 @@ namespace Emby.Server.Implementations.Library
             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 =>
+                var liveStream = i as ILiveStream;
+                if (liveStream != null)
                 {
-                    var liveStream = i as ILiveStream;
-                    if (liveStream != null)
-                    {
-                        return string.Equals(liveStream.UniqueId, uniqueId, StringComparison.OrdinalIgnoreCase);
-                    }
+                    return string.Equals(liveStream.UniqueId, uniqueId, StringComparison.OrdinalIgnoreCase);
+                }
 
-                    return false;
-                });
+                return false;
+            });
 
-                return info as IDirectStreamProvider;
-            }
-            finally
-            {
-                _liveStreamSemaphore.Release();
-            }
+            return Task.FromResult(info as IDirectStreamProvider);
         }
 
         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);
         }
 
-        private async Task<ILiveStream> GetLiveStreamInfo(string id, CancellationToken cancellationToken)
+        private Task<ILiveStream> GetLiveStreamInfo(string id, CancellationToken cancellationToken)
         {
             if (string.IsNullOrEmpty(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;
-                }
-                else
-                {
-                    throw new ResourceNotFoundException();
-                }
+                return Task.FromResult(info);
             }
-            finally
+            else
             {
-                _liveStreamSemaphore.Release();
+                return Task.FromException<ILiveStream>(new ResourceNotFoundException());
             }
         }
 
@@ -844,7 +827,7 @@ namespace Emby.Server.Implementations.Library
 
                     if (liveStream.ConsumerCount <= 0)
                     {
-                        _openStreams.Remove(id);
+                        _openStreams.TryRemove(id, out _);
 
                         _logger.LogInformation("Closing live stream {0}", id);