Imported Upstream version 4.2.0.179

Former-commit-id: 0a113cb3a6feb7873f632839b1307cc6033cd595
This commit is contained in:
Xamarin Public Jenkins
2015-08-26 07:17:56 -04:00
committed by Jo Shields
parent 183bba2c9a
commit 6992685b86
7507 changed files with 90259 additions and 657307 deletions

View File

@@ -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<Tuple<SendOrPostCallback, object, ExecutionContext>> workQueue = new ConcurrentQueue<Tuple<SendOrPostCallback, object, ExecutionContext>> ();
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<SendOrPostCallback, object, ExecutionContext> 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;
@@ -325,6 +363,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);
}
}
}