1 //
2 // ConcurrentExclusiveSchedulerPairTest.cs
3 //
4 // Author:
5 //       Jérémie "garuma" Laval <jeremie.laval@gmail.com>
6 //
7 // Copyright (c) 2011 Jérémie "garuma" Laval
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26 
27 
28 using System;
29 using System.Threading;
30 using System.Threading.Tasks;
31 
32 using NUnit.Framework;
33 
34 namespace MonoTests.System.Threading.Tasks
35 {
36 	[TestFixture]
37 	public class ConcurrentExclusiveSchedulerPairTest
38 	{
39 		ConcurrentExclusiveSchedulerPair schedPair;
40 		TaskFactory factory;
41 
42 		[Test]
BasicExclusiveUsageTest()43 		public void BasicExclusiveUsageTest ()
44 		{
45 			schedPair = new ConcurrentExclusiveSchedulerPair (TaskScheduler.Default, 4);
46 			factory = new TaskFactory (schedPair.ExclusiveScheduler);
47 
48 			bool launched = false;
49 			factory.StartNew (() => launched = true);
50 			Thread.Sleep (600);
51 
52 			Assert.IsTrue (launched);
53 		}
54 
55 		[Test]
BasicConcurrentUsageTest()56 		public void BasicConcurrentUsageTest ()
57 		{
58 			schedPair = new ConcurrentExclusiveSchedulerPair (TaskScheduler.Default, 4);
59 			factory = new TaskFactory (schedPair.ConcurrentScheduler);
60 
61 			bool launched = false;
62 			factory.StartNew (() => launched = true);
63 			Thread.Sleep (600);
64 
65 			Assert.IsTrue (launched);
66 		}
67 
68 		[Test]
ExclusiveUsageTest()69 		public void ExclusiveUsageTest ()
70 		{
71 			schedPair = new ConcurrentExclusiveSchedulerPair (TaskScheduler.Default, 4);
72 			factory = new TaskFactory (schedPair.ExclusiveScheduler);
73 
74 			int count = 0;
75 			ManualResetEventSlim mreFinish = new ManualResetEventSlim (false);
76 			ManualResetEventSlim mreStart = new ManualResetEventSlim (false);
77 
78 			factory.StartNew (() => {
79 					mreStart.Set ();
80 					Interlocked.Increment (ref count);
81 					mreFinish.Wait ();
82 				});
83 			mreStart.Wait ();
84 			factory.StartNew (() => Interlocked.Increment (ref count));
85 			Thread.Sleep (100);
86 
87 			Assert.AreEqual (1, count);
88 			mreFinish.Set ();
89 		}
90 
91 		[Test]
ConcurrentUsageTest()92 		public void ConcurrentUsageTest ()
93 		{
94 			schedPair = new ConcurrentExclusiveSchedulerPair (TaskScheduler.Default, 4);
95 			factory = new TaskFactory (schedPair.ConcurrentScheduler);
96 
97 			int count = 0;
98 			ManualResetEventSlim mreFinish = new ManualResetEventSlim (false);
99 			CountdownEvent cntd = new CountdownEvent (2);
100 
101 			factory.StartNew (() => {
102 					Interlocked.Increment (ref count);
103 					cntd.Signal ();
104 					mreFinish.Wait ();
105 				});
106 			factory.StartNew (() => {
107 					Interlocked.Increment (ref count);
108 					cntd.Signal ();
109 					mreFinish.Wait ();
110 				});
111 
112 			cntd.Wait ();
113 			Assert.AreEqual (2, count);
114 			mreFinish.Set ();
115 		}
116 
117 		[Test]
ConcurrentUsageWithExclusiveExecutingTest()118 		public void ConcurrentUsageWithExclusiveExecutingTest ()
119 		{
120 			schedPair = new ConcurrentExclusiveSchedulerPair (TaskScheduler.Default, 4);
121 			TaskFactory exclFact = new TaskFactory (schedPair.ExclusiveScheduler);
122 			TaskFactory concFact = new TaskFactory (schedPair.ConcurrentScheduler);
123 
124 			int count = 0;
125 			bool exclStarted = false;
126 			ManualResetEventSlim mreStart = new ManualResetEventSlim (false);
127 			ManualResetEventSlim mreFinish = new ManualResetEventSlim (false);
128 
129 			exclFact.StartNew (() => {
130 				exclStarted = true;
131 				mreStart.Set ();
132 				mreFinish.Wait ();
133 				exclStarted = false;
134 			});
135 
136 			mreStart.Wait ();
137 
138 			concFact.StartNew (() => Interlocked.Increment (ref count));
139 			concFact.StartNew (() => Interlocked.Increment (ref count));
140 			Thread.Sleep (100);
141 
142 			Assert.IsTrue (exclStarted);
143 			Assert.AreEqual (0, count);
144 			mreFinish.Set ();
145 		}
146 
147 		[Test]
ExclusiveUsageWithConcurrentExecutingTest()148 		public void ExclusiveUsageWithConcurrentExecutingTest ()
149 		{
150 			schedPair = new ConcurrentExclusiveSchedulerPair (TaskScheduler.Default, 4);
151 			TaskFactory exclFact = new TaskFactory (schedPair.ExclusiveScheduler);
152 			TaskFactory concFact = new TaskFactory (schedPair.ConcurrentScheduler);
153 
154 			int count = 0;
155 			bool started = false;
156 			ManualResetEventSlim mreStart = new ManualResetEventSlim (false);
157 			ManualResetEventSlim mreFinish = new ManualResetEventSlim (false);
158 
159 			concFact.StartNew (() => {
160 				started = true;
161 				mreStart.Set ();
162 				mreFinish.Wait ();
163 				started = false;
164 			});
165 
166 			mreStart.Wait ();
167 
168 			exclFact.StartNew (() => Interlocked.Increment (ref count));
169 			Thread.Sleep (100);
170 
171 			Assert.IsTrue (started);
172 			Assert.AreEqual (0, count);
173 			mreFinish.Set ();
174 		}
175 	}
176 }
177 
178