EventLoop.cs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. #if STRESS
  3. using System;
  4. using System.Linq;
  5. using System.Reactive.Concurrency;
  6. using System.Reactive.Disposables;
  7. using System.Reactive.Linq;
  8. using System.Reflection;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using Xunit;
  12. namespace ReactiveTests.Stress.Schedulers
  13. {
  14. /// <summary>
  15. /// Test for <see href="https://rx.codeplex.com/workitem/37">work item #37</see>.
  16. /// </summary>
  17. public static class EventLoop
  18. {
  19. private static readonly FieldInfo semaphore = typeof(EventLoopScheduler).GetField("_evt", BindingFlags.NonPublic | BindingFlags.Instance);
  20. public static void NoSemaphoreFullException()
  21. {
  22. var failed = new TaskCompletionSource<int>();
  23. using (var scheduler = new EventLoopScheduler())
  24. {
  25. Assert.Equal(0, scheduler.CurrentCount());
  26. var maxCount = Environment.ProcessorCount;
  27. using (Enumerable.Range(1, maxCount)
  28. .Select(_ => scheduler.SchedulePeriodic(TimeSpan.Zero, () =>
  29. {
  30. var count = scheduler.CurrentCount();
  31. if (count > maxCount)
  32. failed.SetResult(count);
  33. }))
  34. .Aggregate(
  35. new CompositeDisposable(),
  36. (c, d) =>
  37. {
  38. c.Add(d);
  39. return c;
  40. }))
  41. {
  42. if (failed.Task.Wait(TimeSpan.FromSeconds(10)))
  43. {
  44. Assert.Fail("Semaphore count is too high: {0}", failed.Task.Result);
  45. }
  46. }
  47. }
  48. }
  49. private static int CurrentCount(this EventLoopScheduler scheduler)
  50. {
  51. #if !NO_CDS
  52. return ((SemaphoreSlim)semaphore.GetValue(scheduler)).CurrentCount;
  53. #else
  54. return 0;
  55. #endif
  56. }
  57. }
  58. }
  59. #endif