test: observe monitor waits without delays
This commit is contained in:
parent
ea17bc8624
commit
fa4bdfe89f
4 changed files with 127 additions and 35 deletions
|
|
@ -270,19 +270,30 @@ public sealed class SilkWindowCallbackBindingTests
|
|||
Task<Exception> first = Task.Run(() => Record.Exception(binding.Dispose));
|
||||
Assert.True(surface.RemoveEntered.Wait(TimeSpan.FromSeconds(5)));
|
||||
using var secondEntered = new ManualResetEventSlim(false);
|
||||
Task<Exception> second = Task.Run(() =>
|
||||
Exception? secondError = null;
|
||||
var secondThread = new Thread(() =>
|
||||
{
|
||||
secondEntered.Set();
|
||||
return Record.Exception(binding.Dispose);
|
||||
});
|
||||
Assert.True(secondEntered.Wait(TimeSpan.FromSeconds(5)));
|
||||
await Task.Delay(50);
|
||||
Assert.False(second.IsCompleted);
|
||||
secondError = Record.Exception(binding.Dispose);
|
||||
})
|
||||
{
|
||||
IsBackground = true,
|
||||
Name = "Silk callback binding concurrent dispose contract",
|
||||
};
|
||||
secondThread.Start();
|
||||
bool secondStartedInTime = secondEntered.Wait(TimeSpan.FromSeconds(5));
|
||||
bool secondBlockedOnDetach = secondStartedInTime && SpinWait.SpinUntil(
|
||||
() => (secondThread.ThreadState & ThreadState.WaitSleepJoin) != 0,
|
||||
TimeSpan.FromSeconds(5));
|
||||
|
||||
surface.ContinueRemove.Set();
|
||||
|
||||
Assert.Null(await first);
|
||||
Assert.Null(await second);
|
||||
bool secondJoined = secondThread.Join(TimeSpan.FromSeconds(5));
|
||||
Assert.True(secondStartedInTime, "the second dispose thread did not start");
|
||||
Assert.True(secondBlockedOnDetach, "the second dispose never waited for physical detach");
|
||||
Assert.True(secondJoined, "the second dispose did not finish after detach completed");
|
||||
Assert.Null(secondError);
|
||||
Assert.True(binding.IsDetached);
|
||||
}
|
||||
|
||||
|
|
@ -306,19 +317,30 @@ public sealed class SilkWindowCallbackBindingTests
|
|||
Task<Exception> first = Task.Run(() => Record.Exception(binding.Dispose));
|
||||
Assert.True(surface.RemoveEntered.Wait(TimeSpan.FromSeconds(5)));
|
||||
using var secondEntered = new ManualResetEventSlim(false);
|
||||
Task<Exception> second = Task.Run(() =>
|
||||
Exception? secondError = null;
|
||||
var secondThread = new Thread(() =>
|
||||
{
|
||||
secondEntered.Set();
|
||||
return Record.Exception(binding.Dispose);
|
||||
});
|
||||
Assert.True(secondEntered.Wait(TimeSpan.FromSeconds(5)));
|
||||
await Task.Delay(50);
|
||||
Assert.False(second.IsCompleted);
|
||||
secondError = Record.Exception(binding.Dispose);
|
||||
})
|
||||
{
|
||||
IsBackground = true,
|
||||
Name = "Silk callback binding detach failure contract",
|
||||
};
|
||||
secondThread.Start();
|
||||
bool secondStartedInTime = secondEntered.Wait(TimeSpan.FromSeconds(5));
|
||||
bool secondBlockedOnDetach = secondStartedInTime && SpinWait.SpinUntil(
|
||||
() => (secondThread.ThreadState & ThreadState.WaitSleepJoin) != 0,
|
||||
TimeSpan.FromSeconds(5));
|
||||
|
||||
surface.ContinueRemove.Set();
|
||||
|
||||
Assert.IsType<AggregateException>(await first);
|
||||
Assert.IsType<AggregateException>(await second);
|
||||
bool secondJoined = secondThread.Join(TimeSpan.FromSeconds(5));
|
||||
Assert.True(secondStartedInTime, "the second dispose thread did not start");
|
||||
Assert.True(secondBlockedOnDetach, "the second dispose never waited for physical detach");
|
||||
Assert.True(secondJoined, "the second dispose did not finish after detach failed");
|
||||
Assert.IsType<AggregateException>(secondError);
|
||||
Assert.False(binding.IsDetached);
|
||||
|
||||
surface.PersistentRemoveFailures.Clear();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue