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=5237e377e38c80d9a73ce149db5dde8934bdc428;hpb=e003c4e8f9e5ffef89a7527595c94d7457abe1a6;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 5237e377e38..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 { @@ -72,6 +73,11 @@ namespace MonoTests.System.Runtime.CompilerServices Interlocked.Increment (ref ic); return false; } + + public override string ToString () + { + return "Scheduler-" + name; + } } class SingleThreadSynchronizationContext : SynchronizationContext @@ -101,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; @@ -205,6 +248,7 @@ namespace MonoTests.System.Runtime.CompilerServices return res.Result; } +#if !MOBILE_STATIC [Test] public void FinishedTaskOnCompleted () { @@ -229,6 +273,8 @@ namespace MonoTests.System.Runtime.CompilerServices Assert.AreEqual (Thread.CurrentThread.IsBackground, mres2.WaitOne (2000), "#2");; } +#endif + [Test] public void CompletionOnSameCustomSynchronizationContext () { @@ -320,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); + } } }