Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ private void DisposeCore()

private void AcquireCore()
{
#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif
Interop.Sys.LowLevelMonitor_Acquire(_nativeMonitor);
}

Expand All @@ -41,6 +44,9 @@ private void ReleaseCore()

private void WaitCore()
{
#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif
Interop.Sys.LowLevelMonitor_Wait(_nativeMonitor);
}

Expand All @@ -54,6 +60,10 @@ private bool WaitCore(int timeoutMilliseconds)
return true;
}

#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif

return Interop.Sys.LowLevelMonitor_TimedWait(_nativeMonitor, timeoutMilliseconds);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,23 +439,31 @@ await executor.Execute(async () =>
[Theory, MemberData(nameof(GetTargetThreadsAndBlockingCalls))]
public async Task WaitAssertsOnJSInteropThreads(Executor executor, NamedCall method)
{
using var cts = CreateTestCaseTimeoutSource();
await executor.Execute(Task () =>
CancellationTokenSource? cts = null;
Comment thread
radekdoulik marked this conversation as resolved.
try
{
Exception? exception = null;
try
{
method.Call(cts.Token);
}
catch (Exception ex)
Thread.ForceBlockingWait((_) => cts = CreateTestCaseTimeoutSource(), null);
await executor.Execute(Task () =>
{
exception = ex;
}
Exception? exception = null;
try
{
method.Call(cts.Token);
}
catch (Exception ex)
{
exception = ex;
}

executor.AssertBlockingWait(exception);
executor.AssertBlockingWait(exception);

return Task.CompletedTask;
}, cts.Token);
return Task.CompletedTask;
}, cts.Token);
}
finally
{
cts?.Dispose();
}
}

[Theory, MemberData(nameof(GetTargetThreads))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,48 @@ public class NamedCall
override public string ToString() => Name;
}

static void LocalCtsIgnoringCall(Action<CancellationToken> action)
{
var cts = new CancellationTokenSource(8);
try {
action(cts.Token);
} catch (OperationCanceledException exception) {
if (exception.CancellationToken != cts.Token)
{
throw;
}
/* ignore the local one */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkhamoyan Radek improved it here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will update in my PR.

}
}

public static IEnumerable<NamedCall> BlockingCalls = new List<NamedCall>
{
new NamedCall { Name = "Task.Wait", Call = delegate (CancellationToken ct) { Task.Delay(10, ct).Wait(ct); }},
new NamedCall { Name = "Task.WaitAll", Call = delegate (CancellationToken ct) { Task.WaitAll(Task.Delay(10, ct)); }},
new NamedCall { Name = "Task.WaitAny", Call = delegate (CancellationToken ct) { Task.WaitAny(Task.Delay(10, ct)); }},
new NamedCall { Name = "ManualResetEventSlim.Wait", Call = delegate (CancellationToken ct) {
using var mr = new ManualResetEventSlim(false);
using var cts = new CancellationTokenSource(8);
try {
mr.Wait(cts.Token);
} catch (OperationCanceledException) { /* ignore */ }
LocalCtsIgnoringCall(mr.Wait);
}},
new NamedCall { Name = "SemaphoreSlim.Wait", Call = delegate (CancellationToken ct) {
using var sem = new SemaphoreSlim(2);
var cts = new CancellationTokenSource(8);
try {
sem.Wait(cts.Token);
} catch (OperationCanceledException) { /* ignore */ }
LocalCtsIgnoringCall(sem.Wait);
}},
new NamedCall { Name = "CancellationTokenSource.ctor", Call = delegate (CancellationToken ct) {
using var cts = new CancellationTokenSource(8);
}},
new NamedCall { Name = "Mutex.WaitOne", Call = delegate (CancellationToken ct) {
using var mr = new ManualResetEventSlim(false);
var mutex = new Mutex();
var thread = new Thread(() => {
mutex.WaitOne();
mr.Set();
Thread.Sleep(50);
mutex.ReleaseMutex();
});
thread.Start();
Thread.ForceBlockingWait((_) => mr.Wait(), null);
mutex.WaitOne();
}},
};

Expand Down