Merge pull request #963 from kebby/master
[mono.git] / mcs / class / corlib / Test / System.Threading / ManualResetEventSlimTests.cs
index 75b124c06117fac041468af9406112dd6a0480fd..0694ef80b63ee7808bf39187837f2dcbd9c59f8f 100644 (file)
@@ -1,7 +1,11 @@
-#if NET_4_0
 // ManualResetEventSlimTests.cs
 //
+// Authors:
+//       Marek Safar (marek.safar@gmail.com)
+//       Jeremie Laval (jeremie.laval@gmail.com)
+//
 // Copyright (c) 2008 Jérémie "Garuma" Laval
+// Copyright (c) 2012 Xamarin, Inc (http://www.xamarin.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +27,8 @@
 //
 //
 
+#if NET_4_0
+
 using System;
 using System.Threading;
 
@@ -214,6 +220,55 @@ namespace MonoTests.System.Threading
                        Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#2");
                }
 
+               [Test]
+               public void WaitHandleConsistencyTest ()
+               {
+                       var mre = new ManualResetEventSlim ();
+                       mre.WaitHandle.WaitOne (0);
+
+                       for (int i = 0; i < 10000; i++) {
+                               int count = 2;
+                               SpinWait wait = new SpinWait ();
+
+                               ThreadPool.QueueUserWorkItem (_ => { mre.Set (); Interlocked.Decrement (ref count); });
+                               ThreadPool.QueueUserWorkItem (_ => { mre.Reset (); Interlocked.Decrement (ref count); });
+
+                               while (count > 0)
+                                       wait.SpinOnce ();
+                               Assert.AreEqual (mre.IsSet, mre.WaitHandle.WaitOne (0));
+                       }
+               }
+
+               [Test]
+               public void WaitWithCancellationTokenAndNotImmediateSetTest ()
+               {
+                       var mres = new ManualResetEventSlim ();
+                       var cts = new CancellationTokenSource ();
+                       ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); mres.Set (); });
+                       Assert.IsTrue (mres.Wait (TimeSpan.FromSeconds (10), cts.Token), "Wait returned false despite event was set.");
+               }
+
+               [Test]
+               public void WaitWithCancellationTokenAndCancel ()
+               {
+                       var mres = new ManualResetEventSlim ();
+                       var cts = new CancellationTokenSource ();
+                       ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); cts.Cancel (); });
+                       try {
+                               mres.Wait (TimeSpan.FromSeconds (10), cts.Token);
+                               Assert.Fail ("Wait did not throw an exception despite cancellation token was cancelled.");
+                       } catch (OperationCanceledException) {
+                       }
+               }
+
+               [Test]
+               public void WaitWithCancellationTokenAndTimeout ()
+               {
+                       var mres = new ManualResetEventSlim ();
+                       var cts = new CancellationTokenSource ();
+                       Assert.IsFalse (mres.Wait (TimeSpan.FromSeconds (1), cts.Token), "Wait returned true despite timeout.");
+               }
+
                [Test]
                public void Dispose ()
                {