You've already forked linux-packaging-mono
Imported Upstream version 6.6.0.89
Former-commit-id: b39a328747c2f3414dc52e009fb6f0aa80ca2492
This commit is contained in:
parent
cf815e07e0
commit
95fdb59ea6
@@ -38,6 +38,7 @@ namespace Mono
|
||||
MONO_NATIVE_PLATFORM_TYPE_AIX = 4,
|
||||
MONO_NATIVE_PLATFORM_TYPE_ANDROID = 5,
|
||||
MONO_NATIVE_PLATFORM_TYPE_FREEBSD = 6,
|
||||
MONO_NATIVE_PLATFORM_TYPE_HAIKU = 7,
|
||||
|
||||
MONO_NATIVE_PLATFORM_TYPE_IPHONE = 0x100,
|
||||
MONO_NATIVE_PLATFORM_TYPE_TV = 0x200,
|
||||
|
@@ -29,9 +29,11 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MonoTests.System.Threading
|
||||
{
|
||||
@@ -496,33 +498,102 @@ namespace MonoTests.System.Threading
|
||||
}
|
||||
}
|
||||
|
||||
[Test] // https://github.com/mono/mono/issues/12421
|
||||
public void EnsurePostIsNotCalled ()
|
||||
[Test] // https://github.com/mono/mono/issues/16759
|
||||
[Category("NotWasm")]
|
||||
public void EnsureCanceledContinuationsAreOnSameThread ()
|
||||
{
|
||||
SynchronizationContext mainContext = SynchronizationContext.Current;
|
||||
var asc = new AssertSyncContext ();
|
||||
SynchronizationContext.SetSynchronizationContext (asc);
|
||||
var ct = new CancellationTokenSource ();
|
||||
var tcs = new TaskCompletionSource<bool> ();
|
||||
ct.Token.Register (() => tcs.TrySetCanceled ());
|
||||
AsyncPump.Run(async delegate {
|
||||
var _tcs = new TaskCompletionSource<bool>();
|
||||
var _cts = new CancellationTokenSource();
|
||||
|
||||
bool taskIsCancelled = false;
|
||||
Action awaitAction = async () => {
|
||||
try { await tcs.Task; }
|
||||
catch (OperationCanceledException) {
|
||||
taskIsCancelled = true;
|
||||
}
|
||||
};
|
||||
awaitAction ();
|
||||
ct.Cancel (); // should not trigger SynchronizationContext.Post
|
||||
Assert.IsTrue (taskIsCancelled);
|
||||
SynchronizationContext.SetSynchronizationContext (mainContext);
|
||||
var curThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
var taskThreadId = 0;
|
||||
var taskIsCancelled = false;
|
||||
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
taskThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
_cts.Cancel();
|
||||
});
|
||||
|
||||
_cts.Token.Register(() => _tcs.TrySetCanceled());
|
||||
try
|
||||
{
|
||||
await _tcs.Task;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Continuation should run on the same thread before the task started.
|
||||
Assert.AreEqual(curThreadId, Thread.CurrentThread.ManagedThreadId, "#1");
|
||||
taskIsCancelled = true;
|
||||
}
|
||||
|
||||
Assert.IsTrue (taskIsCancelled, "#2");
|
||||
Assert.AreNotEqual(taskThreadId, curThreadId, "#3");
|
||||
});
|
||||
}
|
||||
|
||||
class AssertSyncContext : SynchronizationContext
|
||||
public static class AsyncPump
|
||||
{
|
||||
public override void Post (SendOrPostCallback d, object state) =>
|
||||
throw new InvalidOperationException ("SynchronizationContext.Post was not expected.");
|
||||
/// <summary>Runs the specified asynchronous function.</summary>
|
||||
/// <param name="func">The asynchronous function to execute.</param>
|
||||
public static void Run(Func<Task> func)
|
||||
{
|
||||
if (func == null) throw new ArgumentNullException("func");
|
||||
|
||||
var prevCtx = SynchronizationContext.Current;
|
||||
try
|
||||
{
|
||||
// Establish the new context
|
||||
var syncCtx = new SingleThreadSynchronizationContext();
|
||||
SynchronizationContext.SetSynchronizationContext(syncCtx);
|
||||
|
||||
// Invoke the function and alert the context to when it completes
|
||||
var t = func();
|
||||
if (t == null) throw new InvalidOperationException("No task provided.");
|
||||
t.ContinueWith(delegate { syncCtx.Complete(); }, TaskScheduler.Default);
|
||||
|
||||
// Pump continuations and propagate any exceptions
|
||||
syncCtx.RunOnCurrentThread();
|
||||
t.GetAwaiter().GetResult();
|
||||
}
|
||||
finally { SynchronizationContext.SetSynchronizationContext(prevCtx); }
|
||||
}
|
||||
|
||||
/// <summary>Provides a SynchronizationContext that's single-threaded.</summary>
|
||||
private sealed class SingleThreadSynchronizationContext : SynchronizationContext
|
||||
{
|
||||
/// <summary>The queue of work items.</summary>
|
||||
private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> m_queue =
|
||||
new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
|
||||
/// <summary>The processing thread.</summary>
|
||||
private readonly Thread m_thread = Thread.CurrentThread;
|
||||
|
||||
/// <summary>Dispatches an asynchronous message to the synchronization context.</summary>
|
||||
/// <param name="d">The System.Threading.SendOrPostCallback delegate to call.</param>
|
||||
/// <param name="state">The object passed to the delegate.</param>
|
||||
public override void Post(SendOrPostCallback d, object state)
|
||||
{
|
||||
if (d == null) throw new ArgumentNullException("d");
|
||||
m_queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state));
|
||||
}
|
||||
|
||||
/// <summary>Not supported.</summary>
|
||||
public override void Send(SendOrPostCallback d, object state)
|
||||
{
|
||||
throw new NotSupportedException("Synchronously sending is not supported.");
|
||||
}
|
||||
|
||||
/// <summary>Runs an loop to process all queued work items.</summary>
|
||||
public void RunOnCurrentThread()
|
||||
{
|
||||
foreach (var workItem in m_queue.GetConsumingEnumerable())
|
||||
workItem.Key(workItem.Value);
|
||||
}
|
||||
|
||||
/// <summary>Notifies the context that no more work will arrive.</summary>
|
||||
public void Complete() { m_queue.CompleteAdding(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -34,6 +34,60 @@ using NUnit.Framework;
|
||||
|
||||
namespace MonoTests.System {
|
||||
|
||||
public interface SizedObject
|
||||
{
|
||||
long ExpectedSize();
|
||||
}
|
||||
|
||||
public class NoPointer : SizedObject
|
||||
{
|
||||
public long ExpectedSize()
|
||||
{
|
||||
return 2 * IntPtr.Size;
|
||||
}
|
||||
}
|
||||
|
||||
public class TwoPointer : SizedObject
|
||||
{
|
||||
public object field1;
|
||||
public object field2;
|
||||
|
||||
public long ExpectedSize()
|
||||
{
|
||||
return 4*IntPtr.Size;
|
||||
}
|
||||
}
|
||||
|
||||
public class FourPointer : SizedObject
|
||||
{
|
||||
public object field1;
|
||||
public object field2;
|
||||
public object field3;
|
||||
public object field4;
|
||||
|
||||
public long ExpectedSize()
|
||||
{
|
||||
return 6*IntPtr.Size;
|
||||
}
|
||||
}
|
||||
|
||||
public class EightPointer : SizedObject
|
||||
{
|
||||
public object field1;
|
||||
public object field2;
|
||||
public object fiedl3;
|
||||
public object field4;
|
||||
public object field5;
|
||||
public object field6;
|
||||
public object field7;
|
||||
public object field8;
|
||||
|
||||
public long ExpectedSize()
|
||||
{
|
||||
return (long)(10*IntPtr.Size);
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class GCTest {
|
||||
class MyFinalizeObject
|
||||
@@ -71,5 +125,45 @@ namespace MonoTests.System {
|
||||
|
||||
Assert.IsTrue (t.Wait (5000));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public static void TestGetBytesAllocatedForCurrentThread()
|
||||
{
|
||||
|
||||
Func<SizedObject>[] objectAllocators = {
|
||||
() => new NoPointer(),
|
||||
() => new TwoPointer(),
|
||||
() => new FourPointer(),
|
||||
() => new EightPointer()
|
||||
};
|
||||
|
||||
Random r = new Random();
|
||||
|
||||
// Methods trigger allocation when first run.
|
||||
// So this code warms up allocation before measuring.
|
||||
for (int i = 0; i < objectAllocators.Length; i++)
|
||||
{
|
||||
Console.WriteLine(objectAllocators[i]().ExpectedSize());
|
||||
}
|
||||
|
||||
Console.WriteLine(r.Next(1, 10));
|
||||
|
||||
Assert.AreEqual(1L, 1L);
|
||||
|
||||
// End warmup
|
||||
|
||||
long expectedSize = 0;
|
||||
long bytesBeforeAlloc = GC.GetAllocatedBytesForCurrentThread();
|
||||
|
||||
for (int i = 0; i < 10000000; i++)
|
||||
{
|
||||
expectedSize += objectAllocators[r.Next(0, objectAllocators.Length) ]().ExpectedSize();
|
||||
}
|
||||
|
||||
long bytesAfterAlloc = GC.GetAllocatedBytesForCurrentThread();
|
||||
|
||||
Assert.AreEqual(expectedSize, bytesAfterAlloc - bytesBeforeAlloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
4764f928a33575be51d28de55b54259c83148390
|
||||
cfe087d7016cf448a122fee6dfccd92e7bae902c
|
Reference in New Issue
Block a user