// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. #if STRESS using System; using System.Linq; using System.Reactive.Concurrency; using System.Reactive.Disposables; using System.Reactive.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; using Xunit; namespace ReactiveTests.Stress.Schedulers { /// /// Test for work item #37. /// public static class EventLoop { private static readonly FieldInfo semaphore = typeof(EventLoopScheduler).GetField("_evt", BindingFlags.NonPublic | BindingFlags.Instance); public static void NoSemaphoreFullException() { var failed = new TaskCompletionSource(); using (var scheduler = new EventLoopScheduler()) { Assert.Equal(0, scheduler.CurrentCount()); var maxCount = Environment.ProcessorCount; using (Enumerable.Range(1, maxCount) .Select(_ => scheduler.SchedulePeriodic(TimeSpan.Zero, () => { var count = scheduler.CurrentCount(); if (count > maxCount) failed.SetResult(count); })) .Aggregate( new CompositeDisposable(), (c, d) => { c.Add(d); return c; })) { if (failed.Task.Wait(TimeSpan.FromSeconds(10))) { Assert.Fail("Semaphore count is too high: {0}", failed.Task.Result); } } } } private static int CurrentCount(this EventLoopScheduler scheduler) { #if !NO_CDS return ((SemaphoreSlim)semaphore.GetValue(scheduler)).CurrentCount; #else return 0; #endif } } } #endif