Skip to content

Commit

Permalink
more
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelsavara committed Mar 21, 2024
1 parent df00d23 commit 19034d2
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public LowLevelLifoSemaphore(int initialSignalCount, int maximumSignalCount, int
public bool Wait(int timeoutMs, bool spinWait)
{
Debug.Assert(timeoutMs >= -1);
#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif

int spinCount = spinWait ? _spinCount : 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ private void ReleaseCore()

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,10 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)

ArgumentOutOfRangeException.ThrowIfLessThan(millisecondsTimeout, -1);

#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif

if (!IsSet)
{
if (millisecondsTimeout == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ internal bool WaitOneNoCheck(
{
Debug.Assert(millisecondsTimeout >= -1);

#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif

// The field value is modifiable via the public <see cref="WaitHandle.SafeWaitHandle"/> property, save it locally
// to ensure that one instance is used in all places in this method
SafeWaitHandle? waitHandle = _waitHandle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ private int ProcessSignaledWaitState()

public int Wait(int timeoutMilliseconds, bool interruptible, bool isSleep, ref LockHolder lockHolder)
{
#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif
if (isSleep)
{
s_lock.VerifyIsNotLocked();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ public static int Wait(
Debug.Assert(waitHandles.Length > 0);
Debug.Assert(waitHandles.Length <= WaitHandle.MaxWaitHandles);
Debug.Assert(timeoutMilliseconds >= -1);
#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif

ThreadWaitInfo waitInfo = Thread.CurrentThread.WaitInfo;
WaitableObject?[] waitableObjects = waitInfo.GetWaitedObjectArray(waitHandles.Length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ public int Wait(ThreadWaitInfo waitInfo, int timeoutMilliseconds, bool interrupt
Debug.Assert(waitInfo.Thread == Thread.CurrentThread);

Debug.Assert(timeoutMilliseconds >= -1);
#if FEATURE_WASM_MANAGED_THREADS
Thread.AssureBlockingPossible();
#endif

var lockHolder = new LockHolder(s_lock);
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,35 +168,44 @@ static void LocalCtsIgnoringCall(Action<CancellationToken> action)

public static IEnumerable<NamedCall> BlockingCalls = new List<NamedCall>
{
// things that should NOT throw PNSE
new NamedCall { IsBlocking = false, Name = "Console.WriteLine", Call = delegate (CancellationToken ct) { Console.WriteLine("Blocking"); }},
new NamedCall { IsBlocking = false, Name = "Directory.GetCurrentDirectory", Call = delegate (CancellationToken ct) { Directory.GetCurrentDirectory(); }},
new NamedCall { IsBlocking = true, Name = "Task.Wait", Call = delegate (CancellationToken ct) { Task.Delay(10, ct).Wait(ct); }},
new NamedCall { IsBlocking = true, Name = "Task.WaitAll", Call = delegate (CancellationToken ct) { Task.WaitAll(Task.Delay(10, ct)); }},
new NamedCall { IsBlocking = true, Name = "Task.WaitAny", Call = delegate (CancellationToken ct) { Task.WaitAny(Task.Delay(10, ct)); }},
new NamedCall { IsBlocking = false, Name = "CancellationTokenSource.ctor", Call = delegate (CancellationToken ct) {
using var cts = new CancellationTokenSource(8);
}},
new NamedCall { IsBlocking = false, Name = "Task.Delay", Call = delegate (CancellationToken ct) {
Task.Delay(30, ct);
}},
new NamedCall { IsBlocking = false, Name = "new Timer", Call = delegate (CancellationToken ct) {
new Timer((_) => { }, null, 1, -1);
}},

// things which should throw PNSE on sync JSExport and JSWebWorker
new NamedCall { IsBlocking = true, Name = "Task.Wait", Call = delegate (CancellationToken ct) { Task.Delay(30, ct).Wait(ct); }},
new NamedCall { IsBlocking = true, Name = "Task.WaitAll", Call = delegate (CancellationToken ct) { Task.WaitAll(Task.Delay(30, ct)); }},
new NamedCall { IsBlocking = true, Name = "Task.WaitAny", Call = delegate (CancellationToken ct) { Task.WaitAny(Task.Delay(30, ct)); }},
new NamedCall { IsBlocking = true, Name = "ManualResetEventSlim.Wait", Call = delegate (CancellationToken ct) {
using var mr = new ManualResetEventSlim(false);
using var mr = new ManualResetEventSlim(false);
LocalCtsIgnoringCall(mr.Wait);
}},
}},
new NamedCall { IsBlocking = true, Name = "SemaphoreSlim.Wait", Call = delegate (CancellationToken ct) {
using var sem = new SemaphoreSlim(2);
using var sem = new SemaphoreSlim(2);
LocalCtsIgnoringCall(sem.Wait);
}},
/*new NamedCall { IsBlocking = true, Name = "CancellationTokenSource.ctor", Call = delegate (CancellationToken ct) {
using var cts = new CancellationTokenSource(8);
}},
new NamedCall { IsBlocking = true, 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(static (b) => ((ManualResetEventSlim)b).Wait(), mr);
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(static (b) => ((ManualResetEventSlim)b).Wait(), mr);
mutex.WaitOne();
}},
};

public static IEnumerable<object[]> GetTargetThreadsAndBlockingCalls()
Expand Down

0 comments on commit 19034d2

Please sign in to comment.