final class · System.Threading

SemaphoreSlim

public final class SemaphoreSlim

Counts permits: Wait takes one (waiting while there are none), Release gives them back.

Kind
final class
Namespace
System.Threading
Assembly
System.Core
Access
public, final
Source file
Threading.ant

Inheritance

Base classes
Any SemaphoreSlim

Constructors

new(i32 initialCount)
#
new(i32 initialCount, i32 maxCount)
#

Properties

i32 CurrentCount { get; }
#

read-only

Methods

Wait()
#
Wait(i32 milliseconds) : bool
#

Waits at most milliseconds: whether it took a permit.

Release(i32 releaseCount) : i32
#

Gives releaseCount permits back: the count before.

Release() : i32
#
Dispose()
#

Frees what it holds (it must not be used after).

Private and internal members (4)

Mutex mutex
#

private

Condition changed
#

private

i32 count
#

private

i32 most
#

private

Inherited members (5)

Source

SemaphoreSlim as Antril, decompiled from its Larva HIR.

System.Threading.SemaphoreSlim.ant
// System.Threading.SemaphoreSlim — System.Core (decompiled from Larva HIR)

import System;

into namespace System.Threading
{
	/// Counts permits: Wait takes one (waiting while there are none), Release gives them back.
	public final class SemaphoreSlim
	{
		Mutex mutex;
		Condition changed;
		i32 count;
		i32 most;

		public:
			new(i32 initialCount) : (initialCount, 2147483647)
			{
			}

			new(i32 initialCount, i32 maxCount)
			{
				if (initialCount < 0 || maxCount <= 0 || initialCount > maxCount)
					throw new ArgumentOutOfRangeError("SemaphoreSlim: the counts are out of range");
				mutex = new Mutex();
				changed = new Condition();
				count = initialCount;
				most = maxCount;
			}

			Wait()
			{
				mutex.Lock();
				loop (count == 0)
					changed.Wait(mutex);
				count--;
				mutex.Unlock();
			}

			/// Waits at most `milliseconds`: whether it took a permit.
			Wait(i32 milliseconds) : bool
			{
				i64 until = Environment.TickCount64 + (i64)milliseconds;
				mutex.Lock();
				loop (count == 0)
				{
					i64 left = until - Environment.TickCount64;
					if (left <= 0)
					{
						mutex.Unlock();
						return false;
					}
					changed.Wait(mutex, (i32)left);
				}
				count--;
				mutex.Unlock();
				return true;
			}

			/// Gives `releaseCount` permits back: the count before.
			Release(i32 releaseCount) : i32
			{
				mutex.Lock();
				i32 before = count;
				if (releaseCount < 1 || count > most - releaseCount)
				{
					mutex.Unlock();
					throw new InvalidOperationError("SemaphoreSlim: more permits than its maximum");
				}
				count += releaseCount;
				mutex.Unlock();
				if (releaseCount == 1)
					changed.Signal();
				else
					changed.Broadcast();
				return before;
			}

			Release() : i32 => Release(1);

			/// Frees what it holds (it must not be used after).
			Dispose()
			{
				mutex.Dispose();
				changed.Dispose();
			}

			i32 CurrentCount
			{
				get => count;
			}
	}
}
Esc