Skip to content

Commit

Permalink
WASM: Pump timer queue in xharness when running unit tests (dotnet#40278
Browse files Browse the repository at this point in the history
)

* WASM: Pump timer queue in xharness when running unit tests

We only pumped the threadpool but we didn't pump the timer queue inside the xharness runner, so in the case of Task.Delay() it'll schedule a callback on the timer queue and that will never happen which leads to the infinite loop waiting for the test to finish.
To fix that we call an internal method to pump the timer queue like we do for the threadpool.

Requires an xharness bump to include dotnet/xharness#290

Fixes dotnet#38931

* Don't nullref if no timers were started
  • Loading branch information
akoeplinger authored and Jacksondr5 committed Aug 10, 2020
1 parent 6124c9e commit f74e64a
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
]
},
"microsoft.dotnet.xharness.cli": {
"version": "1.0.0-prerelease.20352.2",
"version": "1.0.0-prerelease.20403.2",
"commands": [
"xharness"
]
Expand Down
8 changes: 4 additions & 4 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,13 @@
<Uri>https://github.com/mono/linker</Uri>
<Sha>7c9b806037e88df7eb40a8151808730133676668</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XHarness.TestRunners.Xunit" Version="1.0.0-prerelease.20402.1">
<Dependency Name="Microsoft.DotNet.XHarness.TestRunners.Xunit" Version="1.0.0-prerelease.20403.2">
<Uri>https://github.com/dotnet/xharness</Uri>
<Sha>2cb87a26217ee107e7d764770c44d986b4333c10</Sha>
<Sha>abc6d581ce00214ef763fb8510d1ba0aa54e7717</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XHarness.CLI" Version="1.0.0-prerelease.20402.1">
<Dependency Name="Microsoft.DotNet.XHarness.CLI" Version="1.0.0-prerelease.20403.2">
<Uri>https://github.com/dotnet/xharness</Uri>
<Sha>2cb87a26217ee107e7d764770c44d986b4333c10</Sha>
<Sha>abc6d581ce00214ef763fb8510d1ba0aa54e7717</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
4 changes: 2 additions & 2 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@
<RefOnlyNugetPackagingVersion>4.9.4</RefOnlyNugetPackagingVersion>
<!-- Testing -->
<MicrosoftNETTestSdkVersion>16.8.0-preview-20200730-03</MicrosoftNETTestSdkVersion>
<MicrosoftDotNetXHarnessTestRunnersXunitVersion>1.0.0-prerelease.20402.1</MicrosoftDotNetXHarnessTestRunnersXunitVersion>
<MicrosoftDotNetXHarnessCLIVersion>1.0.0-prerelease.20402.1</MicrosoftDotNetXHarnessCLIVersion>
<MicrosoftDotNetXHarnessTestRunnersXunitVersion>1.0.0-prerelease.20403.2</MicrosoftDotNetXHarnessTestRunnersXunitVersion>
<MicrosoftDotNetXHarnessCLIVersion>1.0.0-prerelease.20403.2</MicrosoftDotNetXHarnessCLIVersion>
<XUnitVersion>2.4.1</XUnitVersion>
<XUnitRunnerVisualStudioVersion>2.4.2</XUnitRunnerVisualStudioVersion>
<CoverletCollectorVersion>1.3.0</CoverletCollectorVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ async ValueTask<int> ValueTaskReturningAsyncMethod(int result)
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public static async Task AwaitTasksAndValueTasks_InTaskAndValueTaskMethods()
{
for (int i = 0; i < 2; i++)
Expand Down Expand Up @@ -522,7 +521,6 @@ async ValueTask<int> ValueTaskInt32ReturningMethod()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task NonGeneric_ConcurrentBuilders_WorkCorrectly()
{
await Task.WhenAll(Enumerable.Range(0, Environment.ProcessorCount).Select(async _ =>
Expand All @@ -540,7 +538,6 @@ static async ValueTask ValueTaskAsync()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task Generic_ConcurrentBuilders_WorkCorrectly()
{
await Task.WhenAll(Enumerable.Range(0, Environment.ProcessorCount).Select(async _ =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace System.Threading.Tasks.Sources.Tests
public class ManualResetValueTaskSourceTests
{
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task ReuseInstanceWithResets_Success()
{
var mrvts = new ManualResetValueTaskSource<int>();
Expand Down Expand Up @@ -84,7 +83,6 @@ public async Task SetResult_BeforeOnCompleted_ResultAvailableSynchronously()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task SetResult_AfterOnCompleted_ResultAvailableAsynchronously()
{
var mrvts = new ManualResetValueTaskSource<int>();
Expand Down Expand Up @@ -133,7 +131,6 @@ public async Task SetException_BeforeOnCompleted_ResultAvailableSynchronously()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task SetException_AfterOnCompleted_ResultAvailableAsynchronously()
{
var mrvts = new ManualResetValueTaskSource<int>();
Expand Down Expand Up @@ -415,7 +412,6 @@ protected override void QueueTask(Task task)
[InlineData(false, true)]
[InlineData(true, false)]
[InlineData(true, true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task AsyncEnumerable_Success(bool awaitForeach, bool asyncIterator)
{
IAsyncEnumerable<int> enumerable = asyncIterator ?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,6 @@ public void Generic_CreateFromValueTaskSource_AsTaskNotIdempotent() // validates
[Theory]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task NonGeneric_CreateFromValueTaskSource_Success(bool sync)
{
var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(0) : ManualResetValueTaskSourceFactory.Delay(1, 0), 0);
Expand All @@ -386,7 +385,6 @@ public async Task NonGeneric_CreateFromValueTaskSource_Success(bool sync)
[Theory]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task Generic_CreateFromValueTaskSource_Success(bool sync)
{
var vt = new ValueTask<int>(sync ? ManualResetValueTaskSourceFactory.Completed(42) : ManualResetValueTaskSourceFactory.Delay(1, 42), 0);
Expand All @@ -401,7 +399,6 @@ public async Task Generic_CreateFromValueTaskSource_Success(bool sync)
[Theory]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task NonGeneric_CreateFromValueTaskSource_Faulted(bool sync)
{
var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(0, new FormatException()) : ManualResetValueTaskSourceFactory.Delay(1, 0, new FormatException()), 0);
Expand All @@ -420,7 +417,6 @@ public async Task NonGeneric_CreateFromValueTaskSource_Faulted(bool sync)
[Theory]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task Generic_CreateFromValueTaskSource_Faulted(bool sync)
{
var vt = new ValueTask<int>(sync ? ManualResetValueTaskSourceFactory.Completed(0, new FormatException()) : ManualResetValueTaskSourceFactory.Delay(1, 0, new FormatException()), 0);
Expand All @@ -439,7 +435,6 @@ public async Task Generic_CreateFromValueTaskSource_Faulted(bool sync)
[Theory]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task NonGeneric_CreateFromValueTaskSource_Canceled(bool sync)
{
var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(0, new OperationCanceledException()) : ManualResetValueTaskSourceFactory.Delay(1, 0, new OperationCanceledException()), 0);
Expand All @@ -458,7 +453,6 @@ public async Task NonGeneric_CreateFromValueTaskSource_Canceled(bool sync)
[Theory]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task Generic_CreateFromValueTaskSource_Canceled(bool sync)
{
var vt = new ValueTask<int>(sync ? ManualResetValueTaskSourceFactory.Completed(0, new OperationCanceledException()) : ManualResetValueTaskSourceFactory.Delay(1, 0, new OperationCanceledException()), 0);
Expand Down Expand Up @@ -578,7 +572,6 @@ ValueTask<int> Create() =>
[InlineData(null)]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task NonGeneric_CreateFromTask_Await_Normal(bool? continueOnCapturedContext)
{
var t = new ValueTask(Task.Delay(1));
Expand All @@ -593,7 +586,6 @@ public async Task NonGeneric_CreateFromTask_Await_Normal(bool? continueOnCapture
[InlineData(null)]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task Generic_CreateFromTask_Await_Normal(bool? continueOnCapturedContext)
{
var t = new ValueTask<int>(Task.Delay(1).ContinueWith(_ => 42));
Expand All @@ -608,7 +600,6 @@ public async Task Generic_CreateFromTask_Await_Normal(bool? continueOnCapturedCo
[InlineData(null)]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task CreateFromValueTaskSource_Await_Normal(bool? continueOnCapturedContext)
{
var mre = new ManualResetValueTaskSource<int>();
Expand All @@ -625,7 +616,6 @@ public async Task CreateFromValueTaskSource_Await_Normal(bool? continueOnCapture
[InlineData(null)]
[InlineData(false)]
[InlineData(true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task Generic_CreateFromValueTaskSource_Await_Normal(bool? continueOnCapturedContext)
{
var mre = new ManualResetValueTaskSource<int>();
Expand Down Expand Up @@ -815,7 +805,6 @@ await Task.Run(async () =>
[InlineData(CtorMode.Result, true)]
[InlineData(CtorMode.Task, true)]
[InlineData(CtorMode.ValueTaskSource, true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task Generic_Awaiter_ContinuesOnCapturedContext(CtorMode mode, bool sync)
{
await Task.Run(async () =>
Expand Down Expand Up @@ -854,7 +843,6 @@ await Task.Run(async () =>
[InlineData(CtorMode.Result, false, true)]
[InlineData(CtorMode.Task, false, true)]
[InlineData(CtorMode.ValueTaskSource, false, true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task NonGeneric_ConfiguredAwaiter_ContinuesOnCapturedContext(CtorMode mode, bool continueOnCapturedContext, bool sync)
{
await Task.Run(async () =>
Expand Down Expand Up @@ -893,7 +881,6 @@ await Task.Run(async () =>
[InlineData(CtorMode.Result, false, true)]
[InlineData(CtorMode.Task, false, true)]
[InlineData(CtorMode.ValueTaskSource, false, true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)]
public async Task Generic_ConfiguredAwaiter_ContinuesOnCapturedContext(CtorMode mode, bool continueOnCapturedContext, bool sync)
{
await Task.Run(async () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ private TimerQueue(int id)
// Called by mini-wasm.c:mono_set_timeout_exec
private static void TimeoutCallback()
{
Run();
int shortestWaitDurationMs = PumpTimerQueue();

if (shortestWaitDurationMs != int.MaxValue)
{
SetTimeout((int)shortestWaitDurationMs, 0);
}
}

private bool SetTimer(uint actualDuration)
Expand All @@ -53,14 +58,18 @@ private bool SetTimer(uint actualDuration)
return true;
}

private static void Run()
private static int PumpTimerQueue() // NOTE: this method is called via reflection by test code
{
int shortestWaitDurationMs;
if (s_scheduledTimersToFire == null)
{
return int.MaxValue;
}

List<TimerQueue> timersToFire = s_scheduledTimersToFire!;
List<TimerQueue> timers;
timers = s_scheduledTimers!;
long currentTimeMs = TickCount64;
shortestWaitDurationMs = int.MaxValue;
int shortestWaitDurationMs = int.MaxValue;
for (int i = timers.Count - 1; i >= 0; --i)
{
TimerQueue timer = timers[i];
Expand Down Expand Up @@ -94,10 +103,7 @@ private static void Run()
timersToFire.Clear();
}

if (shortestWaitDurationMs != int.MaxValue)
{
SetTimeout((int)shortestWaitDurationMs, 0);
}
return shortestWaitDurationMs;
}
}
}

0 comments on commit f74e64a

Please sign in to comment.