diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs
index 245cc8e..7df8547 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs
@@ -220,11 +220,11 @@ public class Entrypoint : IServerEntryPoint
///
private void StartTimer()
{
- if (Plugin.Instance!.AnalyzerTaskIsRunning)
+ if (Entrypoint.AutomaticTaskState == TaskState.Running)
{
_analyzeAgain = true; // Items added during a scan will be included later.
}
- else
+ else if (ScheduledTaskSemaphore.CurrentCount > 0)
{
_logger.LogInformation("Media Library changed, analyzis will start soon!");
_queueTimer.Change(TimeSpan.FromMilliseconds(20000), Timeout.InfiniteTimeSpan);
@@ -252,7 +252,7 @@ public class Entrypoint : IServerEntryPoint
private void PerformAnalysis()
{
_logger.LogInformation("Timer elapsed - start analyzing");
- Plugin.Instance!.AnalyzerTaskIsRunning = true;
+ _autoTaskCompletEvent.Reset();
using (_cancellationTokenSource = new CancellationTokenSource())
{
@@ -303,6 +303,7 @@ public class Entrypoint : IServerEntryPoint
Plugin.Instance!.Configuration.PathRestrictions.Clear();
Plugin.Instance!.AnalyzerTaskIsRunning = false;
_autoTaskCompletEvent.Set();
+ _cancellationTokenSource = null;
// New item detected, start timer again
if (_analyzeAgain)
@@ -316,18 +317,18 @@ public class Entrypoint : IServerEntryPoint
///
/// Method to cancel the automatic task.
///
- public static void CancelAutomaticTask()
+ /// Cancellation token.
+ public static void CancelAutomaticTask(CancellationToken cancellationToken)
{
if (_cancellationTokenSource != null)
{
- Plugin.Instance!.Configuration.PathRestrictions.Clear();
- _cancellationTokenSource.Cancel();
+ if (!_cancellationTokenSource.IsCancellationRequested)
+ {
+ Plugin.Instance!.Configuration.PathRestrictions.Clear();
+ _cancellationTokenSource.Cancel();
+ }
- _autoTaskCompletEvent.Wait(); // Wait for the signal
- _autoTaskCompletEvent.Reset(); // Reset for the next task
-
- _cancellationTokenSource.Dispose(); // Now safe to dispose
- _cancellationTokenSource = null;
+ _autoTaskCompletEvent.Wait(TimeSpan.FromSeconds(60), cancellationToken); // Wait for the signal
}
}
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs
index bd7d4ab..2b297da 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs
@@ -149,11 +149,6 @@ public class Plugin : BasePlugin, IHasWebPages
///
public event EventHandler? AutoSkipCreditsChanged;
- ///
- /// Gets or sets a value indicating whether analysis is running.
- ///
- public bool AnalyzerTaskIsRunning { get; set; } = false;
-
///
/// Gets the results of fingerprinting all episodes.
///
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectCreditsTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectCreditsTask.cs
index bacb457..2f43939 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectCreditsTask.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectCreditsTask.cs
@@ -69,19 +69,22 @@ public class DetectCreditsTask : IScheduledTask
throw new InvalidOperationException("Library manager was null");
}
- // abort if analyzer is already running
- if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
- {
- return Task.CompletedTask;
- }
- else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)
+ // abort automatic analyzer if running
+ if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
- Entrypoint.CancelAutomaticTask();
+ Entrypoint.CancelAutomaticTask(cancellationToken);
+ }
+
+ ScheduledTaskSemaphore.Wait(-1, cancellationToken);
+
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ScheduledTaskSemaphore.Release();
+ return Task.CompletedTask;
}
_logger.LogInformation("Scheduled Task is starting");
- Plugin.Instance!.AnalyzerTaskIsRunning = true;
var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits,
@@ -91,8 +94,7 @@ public class DetectCreditsTask : IScheduledTask
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
- Plugin.Instance!.AnalyzerTaskIsRunning = false;
-
+ ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosCreditsTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosCreditsTask.cs
index f58472c..2b465c5 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosCreditsTask.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosCreditsTask.cs
@@ -68,19 +68,22 @@ public class DetectIntrosCreditsTask : IScheduledTask
throw new InvalidOperationException("Library manager was null");
}
- // abort if analyzer is already running
- if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
- {
- return Task.CompletedTask;
- }
- else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)
+ // abort automatic analyzer if running
+ if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
- Entrypoint.CancelAutomaticTask();
+ Entrypoint.CancelAutomaticTask(cancellationToken);
+ }
+
+ ScheduledTaskSemaphore.Wait(-1, cancellationToken);
+
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ScheduledTaskSemaphore.Release();
+ return Task.CompletedTask;
}
_logger.LogInformation("Scheduled Task is starting");
- Plugin.Instance!.AnalyzerTaskIsRunning = true;
var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
@@ -98,8 +101,7 @@ public class DetectIntrosCreditsTask : IScheduledTask
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
- Plugin.Instance!.AnalyzerTaskIsRunning = false;
-
+ ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosTask.cs
index c92f800..c1f4f57 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosTask.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosTask.cs
@@ -68,19 +68,22 @@ public class DetectIntrosTask : IScheduledTask
throw new InvalidOperationException("Library manager was null");
}
- // abort if analyzer is already running
- if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
- {
- return Task.CompletedTask;
- }
- else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)
+ // abort automatic analyzer if running
+ if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
- Entrypoint.CancelAutomaticTask();
+ Entrypoint.CancelAutomaticTask(cancellationToken);
+ }
+
+ ScheduledTaskSemaphore.Wait(-1, cancellationToken);
+
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ScheduledTaskSemaphore.Release();
+ return Task.CompletedTask;
}
_logger.LogInformation("Scheduled Task is starting");
- Plugin.Instance!.AnalyzerTaskIsRunning = true;
var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
@@ -90,8 +93,7 @@ public class DetectIntrosTask : IScheduledTask
baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken);
- Plugin.Instance!.AnalyzerTaskIsRunning = false;
-
+ ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/ScheduledTaskSemaphore.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/ScheduledTaskSemaphore.cs
new file mode 100644
index 0000000..67b41a2
--- /dev/null
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/ScheduledTaskSemaphore.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Threading;
+
+namespace ConfusedPolarBear.Plugin.IntroSkipper;
+
+internal sealed class ScheduledTaskSemaphore : IDisposable
+{
+ private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
+
+ private ScheduledTaskSemaphore()
+ {
+ }
+
+ public static int CurrentCount => _semaphore.CurrentCount;
+
+ public static bool Wait(int timeout, CancellationToken cancellationToken)
+ {
+ return _semaphore.Wait(timeout, cancellationToken);
+ }
+
+ public static int Release()
+ {
+ return _semaphore.Release();
+ }
+
+ ///
+ /// Dispose.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Protected dispose.
+ ///
+ /// Dispose.
+ private void Dispose(bool disposing)
+ {
+ if (!disposing)
+ {
+ return;
+ }
+
+ _semaphore.Dispose();
+ }
+}