2009-12-02 Jb Evain <jbevain@novell.com>
[mcs.git] / class / corlib / System.Threading / ManualResetEventSlim.cs
blob304ef480c20ec932b438898505d2e91acaec36ea
1 #if NET_4_0
2 // ManuelResetEventSlim.cs
3 //
4 // Copyright (c) 2008 Jérémie "Garuma" Laval
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 // THE SOFTWARE.
26 using System;
27 using System.Diagnostics;
29 namespace System.Threading
31 public class ManualResetEventSlim : IDisposable
33 const int defaultSpinCount = 20;
34 const int isSet = 1;
35 const int isNotSet = 0;
36 readonly int spinCount;
37 readonly SpinWait sw = new SpinWait ();
39 int state;
42 public ManualResetEventSlim () : this(false, 20)
46 public ManualResetEventSlim (bool initState) : this (initState, 20)
50 public ManualResetEventSlim (bool initState, int spinCount)
52 this.state = initState ? isSet : isNotSet;
53 this.spinCount = spinCount;
56 public bool IsSet {
57 get {
58 return state == isSet;
62 public int SpinCount {
63 get {
64 return spinCount;
68 public void Reset ()
70 Interlocked.Exchange (ref state, isNotSet);
73 public void Set ()
75 Interlocked.Exchange (ref state, isSet);
78 public void Wait ()
80 // First spin
81 for (int i = 0; i < spinCount && state == isNotSet; i++)
82 sw.SpinOnce ();
84 // Then, fallback to classic Sleep's yielding
85 while (state == isNotSet)
86 Thread.Sleep (0);
89 public bool Wait (int millisecondsTimeout)
91 if (millisecondsTimeout < -1)
92 throw new ArgumentOutOfRangeException ("millisecondsTimeout",
93 "millisecondsTimeout is a negative number other than -1");
95 if (millisecondsTimeout == -1) {
96 Wait ();
97 return true;
100 Watch s = Watch.StartNew ();
102 // First spin
103 for (int i = 0; i < spinCount && state == isNotSet; i++) {
104 if (s.ElapsedMilliseconds >= millisecondsTimeout)
105 return false;
107 sw.SpinOnce ();
110 // Then, fallback to classic Sleep's yielding
111 while (state == isNotSet) {
112 if (s.ElapsedMilliseconds >= millisecondsTimeout)
113 return false;
115 sw.SpinOnce ();
118 return true;
121 public bool Wait (TimeSpan ts)
123 return Wait ((int)ts.TotalMilliseconds);
126 [MonoTODO]
127 public WaitHandle WaitHandle {
128 get {
129 return null;
133 #region IDisposable implementation
134 public void Dispose ()
136 Dispose(true);
139 protected virtual void Dispose(bool managedRes)
143 #endregion
147 #endif