Skip to content
Merged
Prev Previous commit
Next Next commit
better timeout decrement code
  • Loading branch information
lambdageek committed Apr 20, 2023
commit 86620994c1717cba9a43989397ca9abbb52f5eb4
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,15 @@ private bool WaitForSignal(int timeoutMs)

while (true)
{
int startTicks = Environment.TickCount;
if (!WaitCore(timeoutMs))
int startWaitTicks = timeoutMs != -1 ? Environment.TickCount : 0;
if (timeoutMs == 0 || !WaitCore(timeoutMs))
{
// Unregister the waiter. The wait subsystem used above guarantees that a thread that wakes due to a timeout does
// not observe a signal to the object being waited upon.
_separated._counts.InterlockedDecrementWaiterCount();
return false;
}
int elapsedTicks = Environment.TickCount;
int endWaitTicks = timeoutMs != -1 ? Environment.TickCount : 0;

// Unregister the waiter if this thread will not be waiting anymore, and try to acquire the semaphore
Counts counts = _separated._counts;
Expand Down Expand Up @@ -176,9 +176,11 @@ private bool WaitForSignal(int timeoutMs)

counts = countsBeforeUpdate;
if (timeoutMs != -1) {
int waitMs = elapsedTicks - startTicks;
if (waitMs <= timeoutMs)
int waitMs = endWaitTicks - startWaitTicks;
if (waitMs >= 0 && waitMs < timeoutMs)
timeoutMs -= waitMs;
else
timeoutMs = 0;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,14 @@ private void PrepareAsyncWaitForSignal(int timeoutMs, Action<LowLevelLifoAsyncWa

_onWait();

if (timeoutMs == 0) {
onTimeout (this, state);
return;
}
WaitEntry we = new WaitEntry(this, onSuccess, onTimeout, state)
{
TimeoutMs = timeoutMs,
StartWaitTicks = Environment.TickCount,
StartWaitTicks = timeoutMs != -1 ? Environment.TickCount : 0,
};
PrepareAsyncWaitCore(timeoutMs, we);
// on success calls InternalAsyncWaitSuccess, on timeout calls InternalAsyncWaitTimeout
Expand All @@ -133,7 +137,7 @@ private static void InternalAsyncWaitTimeout(LowLevelLifoAsyncWaitSemaphore self
private static void InternalAsyncWaitSuccess(LowLevelLifoAsyncWaitSemaphore self, WaitEntry internalWaitEntry)
{
WaitEntry we = internalWaitEntry!;
int elapsedTicks = Environment.TickCount;
int endWaitTicks = we.TimeoutMs != -1 ? Environment.TickCount : 0;
// Unregister the waiter if this thread will not be waiting anymore, and try to acquire the semaphore
Counts counts = self._separated._counts;
while (true)
Expand Down Expand Up @@ -169,10 +173,12 @@ private static void InternalAsyncWaitSuccess(LowLevelLifoAsyncWaitSemaphore self
// the CompareExchange - someone took the signal before us.

if (we.TimeoutMs != -1) {
int waitMs = elapsedTicks - we.StartWaitTicks;
if (waitMs <= we.TimeoutMs)
int waitMs = endWaitTicks - we.StartWaitTicks;
if (waitMs >= 0 && waitMs < we.TimeoutMs)
we.TimeoutMs -= waitMs;
we.StartWaitTicks = elapsedTicks;
else
we.TimeoutMs = 0;
we.StartWaitTicks = endWaitTicks;
}
self.PrepareAsyncWaitCore (we.TimeoutMs, we);
// on success calls InternalAsyncWaitSuccess, on timeout calls InternalAsyncWaitTimeout
Expand Down