2 // ManuelResetEventSlim.cs
4 // Copyright (c) 2008 Jérémie "Garuma" Laval
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
27 using System
.Diagnostics
;
29 namespace System
.Threading
31 public class ManualResetEventSlim
: IDisposable
34 const int isNotSet
= 0;
35 const int defaultSpinCount
= 20;
38 readonly int spinCount
;
40 ManualResetEvent handle
;
42 public ManualResetEventSlim () : this(false, defaultSpinCount
)
46 public ManualResetEventSlim (bool initState
) : this (initState
, defaultSpinCount
)
50 public ManualResetEventSlim (bool initState
, int spinCount
)
53 throw new ArgumentOutOfRangeException ("spinCount is less than 0", "spinCount");
55 this.state
= initState
? isSet
: isNotSet
;
56 this.spinCount
= spinCount
;
57 this.handle
= new ManualResetEvent (initState
);
62 return state
== isSet
;
66 public int SpinCount
{
74 Interlocked
.Exchange (ref state
, isNotSet
);
79 Interlocked
.Exchange (ref state
, isSet
);
84 Wait (CancellationToken
.None
);
87 public bool Wait (int millisecondsTimeout
)
89 return Wait (millisecondsTimeout
, CancellationToken
.None
);
92 public bool Wait (TimeSpan ts
)
94 return Wait ((int)ts
.TotalMilliseconds
, CancellationToken
.None
);
97 public void Wait (CancellationToken token
)
102 public bool Wait (int millisecondsTimeout
, CancellationToken token
)
104 if (millisecondsTimeout
< -1)
105 throw new ArgumentOutOfRangeException ("millisecondsTimeout",
106 "millisecondsTimeout is a negative number other than -1");
108 Watch s
= Watch
.StartNew ();
109 SpinWait sw
= new SpinWait ();
112 while (state
== isNotSet
) {
113 if (token
.IsCancellationRequested
)
116 if (millisecondsTimeout
> -1 && s
.ElapsedMilliseconds
> millisecondsTimeout
)
119 if (count
< spinCount
) {
130 public bool Wait (TimeSpan ts
, CancellationToken token
)
132 return Wait ((int)ts
.TotalMilliseconds
, token
);
135 public WaitHandle WaitHandle
{
141 #region IDisposable implementation
142 public void Dispose ()
147 protected virtual void Dispose(bool managedRes
)