Crunchy-Downloader/CRD/Utils/QueueManagement/ProcessingSlotManager.cs
Elwador d9813191ad - Added **Global Pause button** for the download queue [#418](https://github.com/Crunchy-DL/Crunchy-Downloader/issues/418)
- Added **fallback for sync failures** [#407](https://github.com/Crunchy-DL/Crunchy-Downloader/issues/407)
- Added **history setting** to remove non-existent series/episodes on refresh [#420](https://github.com/Crunchy-DL/Crunchy-Downloader/issues/420)
- Added **movies to history**
- Added **queue persistence**
- Changed **download item state handling**
- Changed **download item removal processing**
- Made small changes to **font detection**
- Changed **rate limit error handling**
- Fixed issue where **files were not always cleaned up** for removed downloads
- Fixed **crash when the queue list was modified**
- Fixed **changelog parsing** not handling versions like `vX.X.X.X`, which caused changes to be re-added on every restart
2026-04-20 15:40:58 +02:00

78 lines
No EOL
1.9 KiB
C#

using System;
using System.Threading;
using System.Threading.Tasks;
namespace CRD.Utils.QueueManagement;
public sealed class ProcessingSlotManager{
private readonly SemaphoreSlim semaphore;
private readonly object syncLock = new();
private int limit;
private int borrowedPermits;
public int Limit{
get{
lock (syncLock){
return limit;
}
}
}
public ProcessingSlotManager(int initialLimit){
if (initialLimit < 0)
throw new ArgumentOutOfRangeException(nameof(initialLimit));
limit = initialLimit;
semaphore = new SemaphoreSlim(
initialCount: initialLimit,
maxCount: int.MaxValue);
}
public Task WaitAsync(CancellationToken cancellationToken = default){
return semaphore.WaitAsync(cancellationToken);
}
public void Release(){
lock (syncLock){
if (borrowedPermits > 0){
borrowedPermits--;
return;
}
semaphore.Release();
}
}
public void SetLimit(int newLimit){
if (newLimit < 0)
throw new ArgumentOutOfRangeException(nameof(newLimit));
lock (syncLock){
if (newLimit == limit)
return;
int delta = newLimit - limit;
if (delta > 0){
int giveBackBorrowed = Math.Min(borrowedPermits, delta);
borrowedPermits -= giveBackBorrowed;
int permitsToRelease = delta - giveBackBorrowed;
if (permitsToRelease > 0)
semaphore.Release(permitsToRelease);
} else{
int permitsToRemove = -delta;
while (permitsToRemove > 0 && semaphore.Wait(0)){
permitsToRemove--;
}
borrowedPermits += permitsToRemove;
}
limit = newLimit;
}
}
}