ReaderWriterLockSlimTest.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. //
  2. // ReaderWriterLockSlimTest.cs
  3. //
  4. // Authors:
  5. // Marek Safar ([email protected])
  6. //
  7. // Copyright (C) 2009 Novell, Inc (http://www.novell.com)
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using NUnit.Framework;
  30. using System.Threading;
  31. using System.Linq;
  32. #if NET_4_0
  33. using System.Threading.Tasks;
  34. #endif
  35. namespace MonoTests.System.Threading
  36. {
  37. [TestFixture]
  38. public class ReaderWriterLockSlimTests
  39. {
  40. [Test]
  41. public void DefaultValues ()
  42. {
  43. var v = new ReaderWriterLockSlim ();
  44. Assert.AreEqual (0, v.CurrentReadCount, "1");
  45. Assert.AreEqual (false, v.IsReadLockHeld, "2");
  46. Assert.AreEqual (false, v.IsUpgradeableReadLockHeld, "3");
  47. Assert.AreEqual (false, v.IsWriteLockHeld, "4");
  48. Assert.AreEqual (LockRecursionPolicy.NoRecursion, v.RecursionPolicy, "5");
  49. Assert.AreEqual (0, v.RecursiveReadCount, "6");
  50. Assert.AreEqual (0, v.RecursiveUpgradeCount, "7");
  51. Assert.AreEqual (0, v.RecursiveWriteCount, "8");
  52. Assert.AreEqual (0, v.WaitingReadCount, "9");
  53. Assert.AreEqual (0, v.WaitingUpgradeCount, "10");
  54. Assert.AreEqual (0, v.WaitingWriteCount, "11");
  55. }
  56. [Test]
  57. public void Dispose_Errors ()
  58. {
  59. var v = new ReaderWriterLockSlim ();
  60. v.Dispose ();
  61. try {
  62. v.EnterUpgradeableReadLock ();
  63. Assert.Fail ("1");
  64. } catch (ObjectDisposedException) {
  65. }
  66. try {
  67. v.EnterReadLock ();
  68. Assert.Fail ("2");
  69. } catch (ObjectDisposedException) {
  70. }
  71. try {
  72. v.EnterWriteLock ();
  73. Assert.Fail ("3");
  74. } catch (ObjectDisposedException) {
  75. }
  76. }
  77. [Test]
  78. public void TryEnterReadLock_OutOfRange ()
  79. {
  80. var v = new ReaderWriterLockSlim ();
  81. try {
  82. v.TryEnterReadLock (-2);
  83. Assert.Fail ("1");
  84. } catch (ArgumentOutOfRangeException) {
  85. }
  86. try {
  87. v.TryEnterReadLock (TimeSpan.MaxValue);
  88. Assert.Fail ("2");
  89. } catch (ArgumentOutOfRangeException) {
  90. }
  91. try {
  92. v.TryEnterReadLock (TimeSpan.MinValue);
  93. Assert.Fail ("3");
  94. } catch (ArgumentOutOfRangeException) {
  95. }
  96. }
  97. [Test]
  98. public void TryEnterUpgradeableReadLock_OutOfRange ()
  99. {
  100. var v = new ReaderWriterLockSlim ();
  101. try {
  102. v.TryEnterUpgradeableReadLock (-2);
  103. Assert.Fail ("1");
  104. } catch (ArgumentOutOfRangeException) {
  105. }
  106. try {
  107. v.TryEnterUpgradeableReadLock (TimeSpan.MaxValue);
  108. Assert.Fail ("2");
  109. } catch (ArgumentOutOfRangeException) {
  110. }
  111. try {
  112. v.TryEnterUpgradeableReadLock (TimeSpan.MinValue);
  113. Assert.Fail ("3");
  114. } catch (ArgumentOutOfRangeException) {
  115. }
  116. }
  117. [Test]
  118. public void TryEnterWriteLock_OutOfRange ()
  119. {
  120. var v = new ReaderWriterLockSlim ();
  121. try {
  122. v.TryEnterWriteLock (-2);
  123. Assert.Fail ("1");
  124. } catch (ArgumentOutOfRangeException) {
  125. }
  126. try {
  127. v.TryEnterWriteLock (TimeSpan.MaxValue);
  128. Assert.Fail ("2");
  129. } catch (ArgumentOutOfRangeException) {
  130. }
  131. try {
  132. v.TryEnterWriteLock (TimeSpan.MinValue);
  133. Assert.Fail ("3");
  134. } catch (ArgumentOutOfRangeException) {
  135. }
  136. }
  137. [Test, ExpectedException (typeof (SynchronizationLockException))]
  138. public void ExitReadLock ()
  139. {
  140. var v = new ReaderWriterLockSlim ();
  141. v.ExitReadLock ();
  142. }
  143. [Test, ExpectedException (typeof (SynchronizationLockException))]
  144. public void ExitWriteLock ()
  145. {
  146. var v = new ReaderWriterLockSlim ();
  147. v.ExitWriteLock ();
  148. }
  149. [Test]
  150. public void EnterReadLock_NoRecursionError ()
  151. {
  152. var v = new ReaderWriterLockSlim ();
  153. v.EnterReadLock ();
  154. Assert.AreEqual (1, v.RecursiveReadCount);
  155. try {
  156. v.EnterReadLock ();
  157. Assert.Fail ("1");
  158. } catch (LockRecursionException) {
  159. }
  160. try {
  161. v.EnterWriteLock ();
  162. Assert.Fail ("2");
  163. } catch (LockRecursionException) {
  164. }
  165. }
  166. [Test]
  167. public void EnterReadLock ()
  168. {
  169. var v = new ReaderWriterLockSlim ();
  170. v.EnterReadLock ();
  171. Assert.IsTrue (v.IsReadLockHeld, "A");
  172. Assert.AreEqual (0, v.RecursiveWriteCount, "A1");
  173. Assert.AreEqual (1, v.RecursiveReadCount, "A2");
  174. Assert.AreEqual (0, v.RecursiveUpgradeCount, "A3");
  175. Assert.AreEqual (0, v.WaitingReadCount, "A4");
  176. Assert.AreEqual (0, v.WaitingUpgradeCount, "A5");
  177. Assert.AreEqual (0, v.WaitingWriteCount, "A6");
  178. v.ExitReadLock ();
  179. v.EnterReadLock ();
  180. Assert.IsTrue (v.IsReadLockHeld, "B");
  181. Assert.AreEqual (0, v.RecursiveWriteCount, "B1");
  182. Assert.AreEqual (1, v.RecursiveReadCount, "B2");
  183. Assert.AreEqual (0, v.RecursiveUpgradeCount, "B3");
  184. Assert.AreEqual (0, v.WaitingReadCount, "B4");
  185. Assert.AreEqual (0, v.WaitingUpgradeCount, "B5");
  186. Assert.AreEqual (0, v.WaitingWriteCount, "B6");
  187. v.ExitReadLock ();
  188. }
  189. [Test]
  190. public void EnterWriteLock_NoRecursionError ()
  191. {
  192. var v = new ReaderWriterLockSlim ();
  193. v.EnterWriteLock ();
  194. Assert.AreEqual (1, v.RecursiveWriteCount);
  195. try {
  196. v.EnterWriteLock ();
  197. Assert.Fail ("1");
  198. } catch (LockRecursionException) {
  199. }
  200. try {
  201. v.EnterReadLock ();
  202. Assert.Fail ("2");
  203. } catch (LockRecursionException) {
  204. }
  205. }
  206. [Test]
  207. public void EnterWriteLock ()
  208. {
  209. var v = new ReaderWriterLockSlim ();
  210. v.EnterWriteLock ();
  211. Assert.IsTrue (v.IsWriteLockHeld, "A");
  212. Assert.AreEqual (1, v.RecursiveWriteCount, "A1");
  213. Assert.AreEqual (0, v.RecursiveReadCount, "A2");
  214. Assert.AreEqual (0, v.RecursiveUpgradeCount, "A3");
  215. Assert.AreEqual (0, v.WaitingReadCount, "A4");
  216. Assert.AreEqual (0, v.WaitingUpgradeCount, "A5");
  217. Assert.AreEqual (0, v.WaitingWriteCount, "A6");
  218. v.ExitWriteLock ();
  219. v.EnterWriteLock ();
  220. Assert.IsTrue (v.IsWriteLockHeld, "B");
  221. Assert.AreEqual (1, v.RecursiveWriteCount, "B1");
  222. Assert.AreEqual (0, v.RecursiveReadCount, "B2");
  223. Assert.AreEqual (0, v.RecursiveUpgradeCount, "B3");
  224. Assert.AreEqual (0, v.WaitingReadCount, "B4");
  225. Assert.AreEqual (0, v.WaitingUpgradeCount, "B5");
  226. Assert.AreEqual (0, v.WaitingWriteCount, "B6");
  227. v.ExitWriteLock ();
  228. }
  229. [Test]
  230. public void EnterUpgradeableReadLock_NoRecursionError ()
  231. {
  232. var v = new ReaderWriterLockSlim ();
  233. v.EnterUpgradeableReadLock ();
  234. Assert.AreEqual (1, v.RecursiveUpgradeCount);
  235. try {
  236. v.EnterUpgradeableReadLock ();
  237. Assert.Fail ("2");
  238. } catch (LockRecursionException) {
  239. }
  240. }
  241. [Test]
  242. public void EnterUpgradeableReadLock ()
  243. {
  244. var v = new ReaderWriterLockSlim ();
  245. v.EnterUpgradeableReadLock ();
  246. Assert.IsTrue (v.IsUpgradeableReadLockHeld, "A");
  247. Assert.AreEqual (0, v.RecursiveWriteCount, "A1");
  248. Assert.AreEqual (0, v.RecursiveReadCount, "A2");
  249. Assert.AreEqual (1, v.RecursiveUpgradeCount, "A3");
  250. Assert.AreEqual (0, v.WaitingReadCount, "A4");
  251. Assert.AreEqual (0, v.WaitingUpgradeCount, "A5");
  252. Assert.AreEqual (0, v.WaitingWriteCount, "A6");
  253. v.ExitUpgradeableReadLock ();
  254. v.EnterUpgradeableReadLock ();
  255. Assert.IsTrue (v.IsUpgradeableReadLockHeld, "B");
  256. Assert.AreEqual (0, v.RecursiveWriteCount, "B1");
  257. Assert.AreEqual (0, v.RecursiveReadCount, "B2");
  258. Assert.AreEqual (1, v.RecursiveUpgradeCount, "B3");
  259. Assert.AreEqual (0, v.WaitingReadCount, "B4");
  260. Assert.AreEqual (0, v.WaitingUpgradeCount, "B5");
  261. Assert.AreEqual (0, v.WaitingWriteCount, "B6");
  262. v.EnterReadLock ();
  263. v.ExitUpgradeableReadLock ();
  264. Assert.IsTrue (v.IsReadLockHeld, "C");
  265. Assert.AreEqual (0, v.RecursiveWriteCount, "C1");
  266. Assert.AreEqual (1, v.RecursiveReadCount, "C2");
  267. Assert.AreEqual (0, v.RecursiveUpgradeCount, "C3");
  268. Assert.AreEqual (0, v.WaitingReadCount, "C4");
  269. Assert.AreEqual (0, v.WaitingUpgradeCount, "C5");
  270. Assert.AreEqual (0, v.WaitingWriteCount, "C6");
  271. v.ExitReadLock ();
  272. }
  273. [Test]
  274. public void EnterReadLock_MultiRead ()
  275. {
  276. var v = new ReaderWriterLockSlim ();
  277. int local = 10;
  278. var r = from i in Enumerable.Range (1, 30) select new Thread (() => {
  279. // Just to cause some contention
  280. Thread.Sleep (100);
  281. v.EnterReadLock ();
  282. Assert.AreEqual (10, local);
  283. });
  284. var threads = r.ToList ();
  285. foreach (var t in threads) {
  286. t.Start ();
  287. }
  288. foreach (var t in threads) {
  289. // Console.WriteLine (t.ThreadState);
  290. t.Join ();
  291. }
  292. }
  293. [Test]
  294. public void TryEnterWriteLock_WhileReading ()
  295. {
  296. var v = new ReaderWriterLockSlim ();
  297. AutoResetEvent ev = new AutoResetEvent (false);
  298. AutoResetEvent ev2 = new AutoResetEvent (false);
  299. Thread t1 = new Thread (() => {
  300. v.EnterReadLock ();
  301. ev2.Set ();
  302. ev.WaitOne ();
  303. v.ExitReadLock ();
  304. });
  305. t1.Start ();
  306. ev2.WaitOne ();
  307. Assert.IsFalse (v.TryEnterWriteLock (100));
  308. ev.Set ();
  309. t1.Join ();
  310. Assert.IsTrue (v.TryEnterWriteLock (100));
  311. }
  312. [Test]
  313. public void EnterWriteLock_MultiRead ()
  314. {
  315. var v = new ReaderWriterLockSlim ();
  316. int local = 10;
  317. var r = from i in Enumerable.Range (1, 10) select new Thread (() => {
  318. v.EnterReadLock ();
  319. Assert.AreEqual (11, local);
  320. });
  321. v.EnterWriteLock ();
  322. var threads = r.ToList ();
  323. foreach (var t in threads) {
  324. t.Start ();
  325. }
  326. Thread.Sleep (200);
  327. local = 11;
  328. // FIXME: Don't rely on Thread.Sleep (200)
  329. Assert.AreEqual (0, v.WaitingWriteCount, "in waiting write");
  330. Assert.AreEqual (10, v.WaitingReadCount, "in waiting read");
  331. Assert.AreEqual (0, v.WaitingUpgradeCount, "in waiting upgrade");
  332. v.ExitWriteLock ();
  333. foreach (var t in threads) {
  334. // Console.WriteLine (t.ThreadState);
  335. t.Join ();
  336. }
  337. }
  338. [Test]
  339. public void EnterWriteLock_After_ExitUpgradeableReadLock ()
  340. {
  341. var v = new ReaderWriterLockSlim ();
  342. v.EnterUpgradeableReadLock ();
  343. Assert.IsTrue (v.TryEnterWriteLock (100));
  344. v.ExitWriteLock ();
  345. v.ExitUpgradeableReadLock ();
  346. Assert.IsTrue (v.TryEnterWriteLock (100));
  347. v.ExitWriteLock ();
  348. }
  349. #if NET_4_0
  350. [Test]
  351. public void EnterWriteLockWhileInUpgradeAndOtherWaiting ()
  352. {
  353. var v = new ReaderWriterLockSlim ();
  354. var task2 = new Task(() => {
  355. v.EnterWriteLock();
  356. v.ExitWriteLock();
  357. });
  358. var task1 = new Task(() =>
  359. {
  360. v.EnterUpgradeableReadLock ();
  361. task2.Start ();
  362. Thread.Sleep (100);
  363. v.EnterWriteLock ();
  364. v.ExitWriteLock ();
  365. v.ExitUpgradeableReadLock ();
  366. });
  367. task1.Start ();
  368. Assert.IsTrue (task1.Wait (500));
  369. }
  370. #endif
  371. [Test]
  372. public void RecursiveReadLockTest ()
  373. {
  374. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  375. Assert.IsTrue (v.TryEnterReadLock (100), "#1");
  376. Assert.IsTrue (v.TryEnterReadLock (100), "#2");
  377. Assert.IsTrue (v.TryEnterReadLock (100), "#3");
  378. Assert.AreEqual (3, v.RecursiveReadCount);
  379. }
  380. [Test]
  381. public void RecursiveReadPlusWriteLockTest ()
  382. {
  383. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  384. try {
  385. v.EnterReadLock ();
  386. v.EnterWriteLock ();
  387. Assert.Fail ("1");
  388. } catch (LockRecursionException ex) {
  389. Assert.IsNotNull (ex, "#1");
  390. }
  391. }
  392. [Test]
  393. public void RecursiveReadPlusUpgradeableLockTest ()
  394. {
  395. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  396. try {
  397. v.EnterReadLock ();
  398. v.EnterUpgradeableReadLock ();
  399. Assert.Fail ("1");
  400. } catch (LockRecursionException ex) {
  401. Assert.IsNotNull (ex, "#1");
  402. }
  403. }
  404. [Test]
  405. public void RecursiveWriteLockTest ()
  406. {
  407. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  408. Assert.IsTrue (v.TryEnterWriteLock (100), "#1");
  409. Assert.IsTrue (v.TryEnterWriteLock (100), "#2");
  410. Assert.IsTrue (v.TryEnterWriteLock (100), "#3");
  411. Assert.AreEqual (3, v.RecursiveWriteCount);
  412. }
  413. [Test]
  414. public void RecursiveWritePlusReadLockTest ()
  415. {
  416. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  417. Assert.IsTrue (v.TryEnterWriteLock (100), "#1");
  418. Assert.AreEqual (1, v.RecursiveWriteCount, "1b");
  419. Assert.AreEqual (0, v.RecursiveReadCount, "1c");
  420. Assert.IsTrue (v.TryEnterReadLock (100), "#2");
  421. Assert.AreEqual (1, v.RecursiveWriteCount, "2b");
  422. Assert.AreEqual (1, v.RecursiveReadCount, "2c");
  423. Assert.IsTrue (v.TryEnterReadLock (100), "#3");
  424. Assert.AreEqual (1, v.RecursiveWriteCount, "3b");
  425. Assert.AreEqual (2, v.RecursiveReadCount, "3c");
  426. v.ExitReadLock ();
  427. Assert.AreEqual (1, v.RecursiveWriteCount, "4b");
  428. Assert.AreEqual (1, v.RecursiveReadCount, "4c");
  429. }
  430. [Test]
  431. public void RecursiveUpgradeableReadLockTest ()
  432. {
  433. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  434. Assert.IsTrue (v.TryEnterUpgradeableReadLock (100), "#1");
  435. Assert.IsTrue (v.TryEnterUpgradeableReadLock (100), "#2");
  436. Assert.IsTrue (v.TryEnterUpgradeableReadLock (100), "#3");
  437. Assert.AreEqual (3, v.RecursiveUpgradeCount);
  438. }
  439. [Test]
  440. public void RecursiveReadPropertiesTest ()
  441. {
  442. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  443. v.EnterReadLock ();
  444. v.EnterReadLock ();
  445. Assert.AreEqual (true, v.IsReadLockHeld, "#1a");
  446. Assert.AreEqual (1, v.CurrentReadCount, "#2a");
  447. Assert.AreEqual (2, v.RecursiveReadCount, "#3a");
  448. bool rLock = true;
  449. int cReadCount = -1, rReadCount = -1;
  450. Thread t = new Thread ((_) => {
  451. rLock = v.IsReadLockHeld;
  452. cReadCount = v.CurrentReadCount;
  453. rReadCount = v.RecursiveReadCount;
  454. });
  455. t.Start ();
  456. t.Join ();
  457. Assert.AreEqual (false, rLock, "#1b");
  458. Assert.AreEqual (1, cReadCount, "#2b");
  459. Assert.AreEqual (0, rReadCount, "#3b");
  460. }
  461. [Test]
  462. public void RecursiveUpgradePropertiesTest ()
  463. {
  464. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  465. v.EnterUpgradeableReadLock ();
  466. v.EnterUpgradeableReadLock ();
  467. Assert.AreEqual (true, v.IsUpgradeableReadLockHeld, "#1a");
  468. Assert.AreEqual (false, v.IsReadLockHeld, "#11a");
  469. Assert.AreEqual (0, v.CurrentReadCount, "#2a");
  470. Assert.AreEqual (2, v.RecursiveUpgradeCount, "#3a");
  471. bool upLock = false, rLock = false;
  472. int rCount = -1, rUCount = -1;
  473. Thread t = new Thread ((_) => {
  474. upLock = v.IsUpgradeableReadLockHeld;
  475. rLock = v.IsReadLockHeld;
  476. rCount = v.CurrentReadCount;
  477. rUCount = v.RecursiveUpgradeCount;
  478. });
  479. t.Start ();
  480. t.Join ();
  481. Assert.AreEqual (false, upLock, "#1b");
  482. Assert.AreEqual (false, rLock, "#11b");
  483. Assert.AreEqual (0, rCount, "#2b");
  484. Assert.AreEqual (0, rUCount, "#3b");
  485. }
  486. [Test]
  487. public void RecursiveWritePropertiesTest ()
  488. {
  489. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  490. v.EnterWriteLock ();
  491. v.EnterWriteLock ();
  492. Assert.AreEqual (true, v.IsWriteLockHeld, "#1a");
  493. Assert.AreEqual (2, v.RecursiveWriteCount, "#3a");
  494. bool wLock = false;
  495. int rWrite = -1;
  496. Thread t = new Thread ((_) => {
  497. wLock = v.IsWriteLockHeld;
  498. rWrite = v.RecursiveWriteCount;
  499. });
  500. t.Start ();
  501. t.Join ();
  502. Assert.AreEqual (false, wLock, "#1b");
  503. Assert.AreEqual (0, rWrite, "#3b");
  504. }
  505. [Test]
  506. public void RecursiveEnterExitReadTest ()
  507. {
  508. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  509. v.EnterReadLock ();
  510. v.EnterReadLock ();
  511. v.EnterReadLock ();
  512. Assert.IsTrue (v.IsReadLockHeld);
  513. Assert.AreEqual (3, v.RecursiveReadCount);
  514. v.ExitReadLock ();
  515. Assert.IsTrue (v.IsReadLockHeld);
  516. Assert.AreEqual (2, v.RecursiveReadCount);
  517. }
  518. [Test]
  519. public void RecursiveEnterExitWriteTest ()
  520. {
  521. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  522. v.EnterWriteLock ();
  523. v.EnterWriteLock ();
  524. v.EnterWriteLock ();
  525. Assert.IsTrue (v.IsWriteLockHeld);
  526. Assert.AreEqual (3, v.RecursiveWriteCount);
  527. v.ExitWriteLock ();
  528. v.ExitWriteLock ();
  529. Assert.IsTrue (v.IsWriteLockHeld);
  530. Assert.AreEqual (1, v.RecursiveWriteCount);
  531. }
  532. [Test]
  533. public void RecursiveEnterExitUpgradableTest ()
  534. {
  535. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  536. v.EnterUpgradeableReadLock ();
  537. v.EnterUpgradeableReadLock ();
  538. v.EnterUpgradeableReadLock ();
  539. Assert.IsTrue (v.IsUpgradeableReadLockHeld);
  540. Assert.AreEqual (3, v.RecursiveUpgradeCount);
  541. v.ExitUpgradeableReadLock ();
  542. Assert.IsTrue (v.IsUpgradeableReadLockHeld);
  543. Assert.AreEqual (2, v.RecursiveUpgradeCount);
  544. }
  545. [Test]
  546. public void RecursiveWriteUpgradeReadTest ()
  547. {
  548. var rwlock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
  549. rwlock.EnterWriteLock ();
  550. Assert.IsTrue (rwlock.IsWriteLockHeld);
  551. rwlock.EnterUpgradeableReadLock ();
  552. Assert.IsTrue (rwlock.IsUpgradeableReadLockHeld);
  553. rwlock.EnterReadLock ();
  554. Assert.IsTrue (rwlock.IsReadLockHeld);
  555. rwlock.ExitUpgradeableReadLock();
  556. Assert.IsFalse (rwlock.IsUpgradeableReadLockHeld);
  557. Assert.IsTrue (rwlock.IsReadLockHeld);
  558. Assert.IsTrue (rwlock.IsWriteLockHeld);
  559. rwlock.ExitReadLock ();
  560. Assert.IsTrue (rwlock.IsWriteLockHeld);
  561. }
  562. [Test]
  563. public void RecursiveWriteUpgradeTest ()
  564. {
  565. ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
  566. rwlock.EnterWriteLock ();
  567. Assert.IsTrue (rwlock.IsWriteLockHeld);
  568. rwlock.EnterUpgradeableReadLock ();
  569. Assert.IsTrue (rwlock.IsUpgradeableReadLockHeld);
  570. rwlock.ExitUpgradeableReadLock ();
  571. Assert.IsFalse (rwlock.IsUpgradeableReadLockHeld);
  572. Assert.IsTrue (rwlock.IsWriteLockHeld);
  573. rwlock.ExitWriteLock ();
  574. Assert.IsFalse (rwlock.IsWriteLockHeld);
  575. rwlock.EnterWriteLock ();
  576. Assert.IsTrue (rwlock.IsWriteLockHeld);
  577. }
  578. [Test]
  579. public void RecursiveWriteReadAcquisitionInterleaving ()
  580. {
  581. var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
  582. v.EnterWriteLock ();
  583. Assert.IsTrue (v.IsWriteLockHeld, "#1");
  584. bool result = true;
  585. var t = new Thread (delegate () {
  586. result = v.TryEnterReadLock (100);
  587. });
  588. t.Start ();
  589. t.Join ();
  590. Assert.IsFalse (result, "#2");
  591. v.ExitWriteLock ();
  592. t = new Thread (delegate () {
  593. result = v.TryEnterReadLock (100);
  594. });
  595. t.Start ();
  596. t.Join ();
  597. Assert.IsTrue (result, "#3");
  598. }
  599. }
  600. }