File: src\System\Threading\LowLevelLifoSemaphore.Unix.cs
Web Access
Project: src\src\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj (System.Private.CoreLib)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
 
namespace System.Threading
{
    /// <summary>
    /// A LIFO semaphore implemented using the PAL's semaphore with uninterruptible waits.
    /// </summary>
    internal sealed partial class LowLevelLifoSemaphore : IDisposable
    {
        private Semaphore? _semaphore;
 
        private void Create(int maximumSignalCount)
        {
            Debug.Assert(maximumSignalCount > 0);
            _semaphore = new Semaphore(0, maximumSignalCount);
        }
 
        public bool WaitCore(int timeoutMs)
        {
            Debug.Assert(_semaphore != null);
            Debug.Assert(timeoutMs >= -1);
 
            int waitResult = WaitNative(_semaphore!.SafeWaitHandle, timeoutMs);
            Debug.Assert(waitResult == WaitHandle.WaitSuccess || waitResult == WaitHandle.WaitTimeout);
            return waitResult == WaitHandle.WaitSuccess;
        }
 
        [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_WaitOnePrioritized")]
        private static partial int WaitNative(SafeWaitHandle handle, int timeoutMs);
 
        private void ReleaseCore(int count)
        {
            Debug.Assert(_semaphore != null);
            Debug.Assert(count > 0);
 
            _semaphore!.Release(count);
        }
 
        public void Dispose()
        {
            Debug.Assert(_semaphore != null);
            _semaphore!.Dispose();
        }
    }
}