X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FTest%2FSystem.Runtime.CompilerServices%2FTaskAwaiterTest.cs;h=57b1d2c27642c1dafc45d854a7ccf92f086f1cee;hb=69f207ee9e4f440e66e98bf5f685807f6527c39d;hp=1bc9d38414758f89d626e21e369236701da04839;hpb=7c7ae04f7fa23fb006c799798e9efc52faf54cb8;p=mono.git diff --git a/mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs b/mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs index 1bc9d384147..57b1d2c2764 100644 --- a/mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs @@ -35,6 +35,7 @@ using NUnit.Framework; using System.Runtime.CompilerServices; using System.Collections.Generic; using System.Collections; +using System.Collections.Concurrent; namespace MonoTests.System.Runtime.CompilerServices { @@ -106,6 +107,43 @@ namespace MonoTests.System.Runtime.CompilerServices } } + class NestedSynchronizationContext : SynchronizationContext + { + Thread thread; + readonly ConcurrentQueue> workQueue = new ConcurrentQueue> (); + readonly AutoResetEvent workReady = new AutoResetEvent (false); + + public NestedSynchronizationContext () + { + thread = new Thread (WorkerThreadProc) { IsBackground = true }; + thread.Start (); + } + + public override void Post (SendOrPostCallback d, object state) + { + var context = ExecutionContext.Capture (); + workQueue.Enqueue (Tuple.Create (d, state, context)); + workReady.Set (); + } + + void WorkerThreadProc () + { + if (!workReady.WaitOne (10000)) + return; + + Tuple work; + + while (workQueue.TryDequeue (out work)) { + ExecutionContext.Run (work.Item3, _ => { + var oldSyncContext = SynchronizationContext.Current; + SynchronizationContext.SetSynchronizationContext (this); + work.Item1 (_); + SynchronizationContext.SetSynchronizationContext (oldSyncContext); + }, work.Item2); + } + } + } + string progress; SynchronizationContext sc; ManualResetEvent mre; @@ -210,6 +248,7 @@ namespace MonoTests.System.Runtime.CompilerServices return res.Result; } +#if !MOBILE_STATIC [Test] public void FinishedTaskOnCompleted () { @@ -234,6 +273,8 @@ namespace MonoTests.System.Runtime.CompilerServices Assert.AreEqual (Thread.CurrentThread.IsBackground, mres2.WaitOne (2000), "#2");; } +#endif + [Test] public void CompletionOnSameCustomSynchronizationContext () { @@ -325,6 +366,33 @@ namespace MonoTests.System.Runtime.CompilerServices SynchronizationContext.SetSynchronizationContext (null); } + + [Test] + public void NestedLeakingSynchronizationContext () + { + var sc = SynchronizationContext.Current; + if (sc == null) + Assert.IsTrue (NestedLeakingSynchronizationContext_MainAsync (sc).Wait (5000), "#1"); + else + Assert.Ignore ("NestedSynchronizationContext may never complete on custom context"); + } + + static async Task NestedLeakingSynchronizationContext_MainAsync (SynchronizationContext sc) + { + Assert.AreSame (sc, SynchronizationContext.Current, "#1"); + await NestedLeakingSynchronizationContext_DoWorkAsync (); + Assert.AreSame (sc, SynchronizationContext.Current, "#2"); + } + + static async Task NestedLeakingSynchronizationContext_DoWorkAsync () + { + var sc = new NestedSynchronizationContext (); + SynchronizationContext.SetSynchronizationContext (sc); + + Assert.AreSame (sc, SynchronizationContext.Current); + await Task.Yield (); + Assert.AreSame (sc, SynchronizationContext.Current); + } } }