-#if NET_4_0
// CountdownEvent.cs
//
// Copyright (c) 2008 Jérémie "Garuma" Laval
using System;
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
namespace System.Threading
{
public class CountdownEvent : IDisposable
{
int count;
readonly int initial;
- bool isCanceled;
ManualResetEvent evt = new ManualResetEvent (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 (value < 0)
throw new InvalidOperationException ("the specified count is larger that CurrentCount");
- if (IsCanceled)
- throw new OperationCanceledException ();
};
int newValue;
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) {
- if (IsCanceled)
- throw new OperationCanceledException ();
- };
-
- 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 (CancellationToken token)
+ {
+ Wait (() => token.IsCancellationRequested);
+ }
+
public bool Wait (int timeoutMilli)
{
if (timeoutMilli == -1) {
public bool IsSet {
get {
- return count <= 0;
+ return count == 0;
}
}
{
}
- #endregion
-
-
- #region ISupportsCancellation implementation
- public void Cancel ()
+ protected virtual void Dispose (bool managedRes)
{
- Interlocked.Exchange (ref count, 0);
- isCanceled = true;
- }
-
- public bool IsCanceled {
- get {
- return isCanceled;
- }
+
}
-
- #endregion
-
+ #endregion
}
}
#endif