// 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;
}
}
}
}