public virtual void DoWait(IQueuedSync sync)
{
lock (this)
{
if (!sync.Recheck(this))
{
try
{
while (_waiting) Monitor.Wait(this);
}
catch (ThreadInterruptedException ex)
{
if (_waiting)
{
// no notification
_waiting = false; // invalidate for the signaller
throw ex.PreserveStackTrace();
}
// thread was interrupted after it was notified
Thread.CurrentThread.Interrupt();
return;
}
}
}
}
public override void LockInterruptibly() { var caller = Thread.CurrentThread; lock (this) { if (GetHold(caller)) return; } var n = new WaitNode(); n.DoWait(this); }