// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Threading; using System.Threading.Tasks; namespace EpicGames.Horde.Utilities { /// /// Wraps a semaphore controlling the number of open files at any time. Used to prevent exceeding handle limit on MacOS. /// class PlatformFileLock : IDisposable { static readonly SemaphoreSlim? s_semaphore = CreateSemaphore(); bool _locked; private PlatformFileLock() => _locked = true; /// /// Acquire the platform file lock /// /// Cancellation token for the operation public static async ValueTask CreateAsync(CancellationToken cancellationToken) { if (s_semaphore != null) { await s_semaphore.WaitAsync(cancellationToken); return new PlatformFileLock(); } return null; } /// public void Dispose() { if (_locked) { s_semaphore?.Release(); _locked = true; } } static SemaphoreSlim? CreateSemaphore() { if (OperatingSystem.IsMacOS()) { return new SemaphoreSlim(32); } else { return null; } } } }