Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / AsyncSemaphore.cs @ dccd340f

History | View | Annotate | Download (1.8 kB)

1
// -----------------------------------------------------------------------
2
// <copyright file="AsyncSemaphore.cs" company="Microsoft">
3
// TODO: Update copyright text.
4
// </copyright>
5
// -----------------------------------------------------------------------
6

    
7
using System.Threading.Tasks;
8

    
9
namespace Pithos.Core
10
{
11
    using System;
12
    using System.Collections.Generic;
13
    using System.Linq;
14
    using System.Text;
15

    
16
    /// <summary>
17
    /// TODO: Update summary.
18
    /// </summary>
19
    public class AsyncSemaphore
20
    {
21
        private readonly static Task s_completed = TaskEx.FromResult(true);
22
        private readonly Queue<TaskCompletionSource<bool>> m_waiters = new Queue<TaskCompletionSource<bool>>();
23
        private int m_currentCount; 
24

    
25
        public AsyncSemaphore(int initialCount)
26
        {
27
            if (initialCount < 0) throw new ArgumentOutOfRangeException("initialCount");
28
            m_currentCount = initialCount; 
29
        }
30
        public Task WaitAsync()
31
        {
32

    
33
            lock (m_waiters)
34
            {
35
                if (m_currentCount > 0)
36
                {
37
                    --m_currentCount;
38
                    return s_completed;
39
                }
40
                else
41
                {
42
                    var waiter = new TaskCompletionSource<bool>();
43
                    m_waiters.Enqueue(waiter);
44
                    return waiter.Task;
45
                }
46
            }
47

    
48
        }
49

    
50
        public void Release()
51
        {
52
            TaskCompletionSource<bool> toRelease = null;
53
            lock (m_waiters)
54
            {
55
                if (m_waiters.Count > 0)
56
                    toRelease = m_waiters.Dequeue();
57
                else
58
                    ++m_currentCount;
59
            }
60
            if (toRelease != null)
61
                toRelease.SetResult(true);
62
        }
63
    }
64
}