1 // ManualResetEventSlimTests.cs
4 // Marek Safar (marek.safar@gmail.com)
5 // Jeremie Laval (jeremie.laval@gmail.com)
7 // Copyright (c) 2008 Jérémie "Garuma" Laval
8 // Copyright (c) 2012 Xamarin, Inc (http://www.xamarin.com)
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33 using System.Threading;
35 using NUnit.Framework;
37 using MonoTests.System.Threading.Tasks;
39 namespace MonoTests.System.Threading
43 public class ManualResetEventSlimTests
45 ManualResetEventSlim mre;
50 mre = new ManualResetEventSlim();
54 public void Constructor_Defaults ()
56 Assert.IsFalse (mre.IsSet, "#1");
57 Assert.AreEqual (10, mre.SpinCount, "#2");
61 public void Constructor_Invalid ()
64 new ManualResetEventSlim (true, -1);
66 } catch (ArgumentException) {
70 new ManualResetEventSlim (true, 2048);
72 } catch (ArgumentException) {
77 public void IsSetTestCase()
79 Assert.IsFalse(mre.IsSet, "#1");
81 Assert.IsTrue(mre.IsSet, "#2");
83 Assert.IsFalse(mre.IsSet, "#3");
87 public void WaitTest()
92 ParallelTestHelper.ParallelStressTest(mre, delegate (ManualResetEventSlim m) {
93 if (Interlocked.Increment(ref count) % 2 == 0) {
95 for (int i = 0; i < 10; i++) {
107 Assert.IsTrue(s, "#1");
108 Assert.IsTrue(mre.IsSet, "#2");
112 public void Wait_SetConcurrent ()
114 for (int i = 0; i < 10000; ++i) {
115 var mre = new ManualResetEventSlim ();
118 ThreadPool.QueueUserWorkItem (delegate {
122 ThreadPool.QueueUserWorkItem (delegate {
123 b &= mre.Wait (1000);
126 Assert.IsTrue (mre.Wait (1000), i.ToString ());
127 Assert.IsTrue (b, i.ToString ());
132 public void Wait_DisposeWithCancel ()
134 var token = new CancellationTokenSource ();
135 ThreadPool.QueueUserWorkItem (delegate {
142 mre.Wait (10000, token.Token);
144 } catch (OperationCanceledException e) {
149 public void Wait_Expired ()
151 Assert.IsFalse (mre.Wait (10));
154 [Test, ExpectedException (typeof (ObjectDisposedException))]
155 public void WaitAfterDisposeTest ()
162 public void SetAfterDisposeTest ()
164 ParallelTestHelper.Repeat (delegate {
165 Exception disp = null, setting = null;
167 CountdownEvent evt = new CountdownEvent (2);
168 CountdownEvent evtFinish = new CountdownEvent (2);
170 ThreadPool.QueueUserWorkItem (delegate {
175 } catch (Exception e) {
180 ThreadPool.QueueUserWorkItem (delegate {
185 } catch (Exception e) {
191 bool bb = evtFinish.Wait (1000);
193 Assert.AreEqual (true, evtFinish.IsSet);
195 Assert.IsTrue (bb, "#0");
196 Assert.IsNull (disp, "#1");
197 Assert.IsNull (setting, "#2");
200 evtFinish.Dispose ();
205 public void WaitHandle_Initialized ()
207 var mre = new ManualResetEventSlim (true);
208 Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#1");
210 Assert.IsFalse (mre.WaitHandle.WaitOne (0), "#2");
211 Assert.AreEqual (mre.WaitHandle, mre.WaitHandle, "#3");
215 public void WaitHandle_NotInitialized ()
217 var mre = new ManualResetEventSlim (false);
218 Assert.IsFalse (mre.WaitHandle.WaitOne (0), "#1");
220 Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#2");
224 public void WaitHandleConsistencyTest ()
226 var mre = new ManualResetEventSlim ();
227 mre.WaitHandle.WaitOne (0);
229 for (int i = 0; i < 10000; i++) {
231 SpinWait wait = new SpinWait ();
233 ThreadPool.QueueUserWorkItem (_ => { while (count > 1) wait.SpinOnce (); mre.Set (); Interlocked.Decrement (ref count); });
234 ThreadPool.QueueUserWorkItem (_ => { mre.Reset (); Interlocked.Decrement (ref count); });
238 Assert.AreEqual (mre.IsSet, mre.WaitHandle.WaitOne (0));
243 public void WaitWithCancellationTokenAndNotImmediateSetTest ()
245 var mres = new ManualResetEventSlim ();
246 var cts = new CancellationTokenSource ();
247 ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); mres.Set (); });
248 Assert.IsTrue (mres.Wait (TimeSpan.FromSeconds (10), cts.Token), "Wait returned false despite event was set.");
252 public void WaitWithCancellationTokenAndCancel ()
254 var mres = new ManualResetEventSlim ();
255 var cts = new CancellationTokenSource ();
256 ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); cts.Cancel (); });
258 mres.Wait (TimeSpan.FromSeconds (10), cts.Token);
259 Assert.Fail ("Wait did not throw an exception despite cancellation token was cancelled.");
260 } catch (OperationCanceledException) {
265 public void WaitWithCancellationTokenAndTimeout ()
267 var mres = new ManualResetEventSlim ();
268 var cts = new CancellationTokenSource ();
269 Assert.IsFalse (mres.Wait (TimeSpan.FromSeconds (1), cts.Token), "Wait returned true despite timeout.");
273 public void Dispose ()
275 var mre = new ManualResetEventSlim (false);
277 Assert.IsFalse (mre.IsSet, "#0a");
282 } catch (ObjectDisposedException) {
290 } catch (ObjectDisposedException) {
294 var v = mre.WaitHandle;
296 } catch (ObjectDisposedException) {
301 public void Dispose_Double ()
303 var mre = new ManualResetEventSlim ();