root / trunk / Pithos.Core / Agents / AsyncSemaphore.cs @ 174bbb6e
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 |
} |