// ----------------------------------------------------------------------- // // TODO: Update copyright text. // // ----------------------------------------------------------------------- using System.Threading.Tasks; namespace Pithos.Core { using System; using System.Collections.Generic; using System.Linq; using System.Text; /// /// TODO: Update summary. /// public class AsyncSemaphore { private readonly static Task s_completed = TaskEx.FromResult(true); private readonly Queue> m_waiters = new Queue>(); private int m_currentCount; public AsyncSemaphore(int initialCount) { if (initialCount < 0) throw new ArgumentOutOfRangeException("initialCount"); m_currentCount = initialCount; } public Task WaitAsync() { lock (m_waiters) { if (m_currentCount > 0) { --m_currentCount; return s_completed; } else { var waiter = new TaskCompletionSource(); m_waiters.Enqueue(waiter); return waiter.Task; } } } public void Release() { TaskCompletionSource toRelease = null; lock (m_waiters) { if (m_waiters.Count > 0) toRelease = m_waiters.Dequeue(); else ++m_currentCount; } if (toRelease != null) toRelease.SetResult(true); } } }