-#if NET_4_0
// CountdownEvent.cs
//
// Copyright (c) 2008 Jérémie "Garuma" Laval
//
//
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
using System;
namespace System.Threading
{
int count;
readonly int initial;
- ManualResetEvent evt = new ManualResetEvent (false);
+ ManualResetEventSlim evt = new ManualResetEventSlim (false);
public CountdownEvent (int count)
{
public bool Signal (int num)
{
- if (num < 0)
+ if (num <= 0)
throw new ArgumentOutOfRangeException ("num");
Action<int> check = delegate (int value) {
if (!ApplyOperation (-num, check, out newValue))
throw new InvalidOperationException ("The event is already set");
- if (newValue <= 0) {
+ if (newValue == 0) {
evt.Set ();
return true;
}
if (num < 0)
throw new ArgumentOutOfRangeException ("num");
- Action<int> check = delegate (int value) { };
-
- return ApplyOperation (num, check);
+ return ApplyOperation (num, null);
}
bool ApplyOperation (int num, Action<int> doCheck)
newValue = 0;
do {
- if (IsSet)
+ oldCount = count;
+ if (oldCount == 0)
return false;
- oldCount = count;
newValue = oldCount + num;
- doCheck (newValue);
-
+ if (doCheck != null)
+ doCheck (newValue);
} while (Interlocked.CompareExchange (ref count, newValue, oldCount) != oldCount);
return true;
public void Wait ()
{
- SpinWait wait = new SpinWait ();
- while (!IsSet) {
- wait.SpinOnce ();
- }
+ evt.Wait ();
}
- public bool Wait (CancellationToken token)
+ public void Wait (CancellationToken token)
{
- return Wait (() => token.IsCancellationRequested);
+ evt.Wait (token);
}
public bool Wait (int timeoutMilli)
{
- if (timeoutMilli == -1) {
- Wait ();
- return true;
- }
-
- Watch sw = Watch.StartNew ();
- long timeout = (long)timeoutMilli;
-
- bool result = Wait (() => sw.ElapsedMilliseconds > timeout);
- sw.Stop ();
-
- return result;
+ return evt.Wait (timeoutMilli);
}
public bool Wait(TimeSpan span)
{
- return Wait ((int)span.TotalMilliseconds);
+ return evt.Wait (span);
}
public bool Wait (int timeoutMilli, CancellationToken token)
{
- if (timeoutMilli == -1) {
- Wait ();
- return true;
- }
-
- Watch sw = Watch.StartNew ();
- long timeout = (long)timeoutMilli;
-
- bool result = Wait (() => sw.ElapsedMilliseconds > timeout || token.IsCancellationRequested);
- sw.Stop ();
-
- return result;
+ return evt.Wait (timeoutMilli, token);
}
public bool Wait(TimeSpan span, CancellationToken token)
{
- return Wait ((int)span.TotalMilliseconds, token);
+ return evt.Wait (span, token);
}
-
- bool Wait (Func<bool> waitPredicate)
- {
- SpinWait wait = new SpinWait ();
-
- while (!IsSet) {
- if (waitPredicate ())
- return false;
- wait.SpinOnce ();
- }
-
- return true;
- }
-
+
public void Reset ()
{
Reset (initial);
public bool IsSet {
get {
- return count <= 0;
+ return count == 0;
}
}
public WaitHandle WaitHandle {
get {
- return evt;
+ return evt.WaitHandle;
}
}