From 9154f20b3404fb818b8c2e74af038547d2c16c40 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Fri, 4 Jun 2021 06:36:58 -0600 Subject: [PATCH] Don't dispose managed CancellationTokenSource (#6139) --- .../Controllers/DynamicHlsController.cs | 3 +- .../Controllers/VideoHlsController.cs | 1 + Jellyfin.Api/Controllers/VideosController.cs | 1 + Jellyfin.Api/Helpers/AudioHelper.cs | 2 ++ Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 1 + Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 4 +-- .../Models/PlaybackDtos/TranscodingJobDto.cs | 28 ++++++++++++++++++- 7 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 555062e556..62283d038d 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1190,7 +1190,8 @@ namespace Jellyfin.Api.Controllers throw new ArgumentException("StartTimeTicks is not allowed."); } - using var cancellationTokenSource = new CancellationTokenSource(); + // CTS lifecycle is managed internally. + var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; using var state = await StreamingHelpers.GetStreamingState( diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs index 308334b237..6a720b1a45 100644 --- a/Jellyfin.Api/Controllers/VideoHlsController.cs +++ b/Jellyfin.Api/Controllers/VideoHlsController.cs @@ -265,6 +265,7 @@ namespace Jellyfin.Api.Controllers EnableSubtitlesInManifest = enableSubtitlesInManifest ?? true }; + // CTS lifecycle is managed internally. var cancellationTokenSource = new CancellationTokenSource(); using var state = await StreamingHelpers.GetStreamingState( streamingRequest, diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index e544d001ed..dc64a0f1bc 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -373,6 +373,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] Dictionary streamOptions) { var isHeadRequest = Request.Method == System.Net.WebRequestMethods.Http.Head; + // CTS lifecycle is managed internally. var cancellationTokenSource = new CancellationTokenSource(); var streamingRequest = new VideoRequestDto { diff --git a/Jellyfin.Api/Helpers/AudioHelper.cs b/Jellyfin.Api/Helpers/AudioHelper.cs index cf35ee23aa..264131905f 100644 --- a/Jellyfin.Api/Helpers/AudioHelper.cs +++ b/Jellyfin.Api/Helpers/AudioHelper.cs @@ -97,6 +97,8 @@ namespace Jellyfin.Api.Helpers } bool isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == System.Net.WebRequestMethods.Http.Head; + + // CTS lifecycle is managed internally. var cancellationTokenSource = new CancellationTokenSource(); using var state = await StreamingHelpers.GetStreamingState( diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs index fcada0e77c..dc5d6715b5 100644 --- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs +++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs @@ -106,6 +106,7 @@ namespace Jellyfin.Api.Helpers bool enableAdaptiveBitrateStreaming) { var isHeadRequest = _httpContextAccessor.HttpContext?.Request.Method == WebRequestMethods.Http.Head; + // CTS lifecycle is managed internally. var cancellationTokenSource = new CancellationTokenSource(); return await GetMasterPlaylistInternal( streamingRequest, diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index b4db0c83e9..c295af7eb3 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -269,7 +269,7 @@ namespace Jellyfin.Api.Helpers { _activeTranscodingJobs.Remove(job); - if (!job.CancellationTokenSource!.IsCancellationRequested) + if (job.CancellationTokenSource?.IsCancellationRequested == false) { job.CancellationTokenSource.Cancel(); } @@ -751,7 +751,7 @@ namespace Jellyfin.Api.Helpers _logger.LogError("FFmpeg exited with code {0}", process.ExitCode); } - process.Dispose(); + job.Dispose(); } private async Task AcquireResources(StreamState state, CancellationTokenSource cancellationTokenSource) diff --git a/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs b/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs index 9edc19bb6d..291e571dcb 100644 --- a/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs +++ b/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs @@ -11,7 +11,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos /// /// Class TranscodingJob. /// - public class TranscodingJobDto + public class TranscodingJobDto : IDisposable { /// /// The process lock. @@ -249,5 +249,31 @@ namespace Jellyfin.Api.Models.PlaybackDtos } } } + + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Dispose all resources. + /// + /// Whether to dispose all resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + Process?.Dispose(); + Process = null; + KillTimer?.Dispose(); + KillTimer = null; + CancellationTokenSource?.Dispose(); + CancellationTokenSource = null; + TranscodingThrottler?.Dispose(); + TranscodingThrottler = null; + } + } } }