System.Threading.Barrier.DiscontinuousWait C# (CSharp) Method

DiscontinuousWait() private method

The reason of discontinuous waiting instead of direct waiting on the event is to avoid the race where the sense is changed twice because the next phase is finished (due to either RemoveParticipant is called or another thread joined the next phase instead of the current thread) so the current thread will be stuck on the event because it is reset back The maxwait and the shift numbers are arbitrarily choosen, there were no references picking them
private DiscontinuousWait ( ManualResetEventSlim currentPhaseEvent, int totalTimeout, CancellationToken token, long observedPhase ) : bool
currentPhaseEvent ManualResetEventSlim The current phase event
totalTimeout int wait timeout in milliseconds
token CancellationToken cancellation token passed to SignalAndWait
observedPhase long The current phase number for this thread
return bool
        private bool DiscontinuousWait(ManualResetEventSlim currentPhaseEvent, int totalTimeout, CancellationToken token, long observedPhase)
        {
            int maxWait = 100; // 100 ms
            int waitTimeCeiling = 10000; // 10 seconds
            while (observedPhase == CurrentPhaseNumber)
            {
                // the next wait time, the min of the maxWait and the totalTimeout
                int waitTime = totalTimeout == Timeout.Infinite ? maxWait : Math.Min(maxWait, totalTimeout);

                if (currentPhaseEvent.Wait(waitTime, token))
                    return true;

                //update the total wait time
                if (totalTimeout != Timeout.Infinite)
                {
                    totalTimeout -= waitTime;
                    if (totalTimeout <= 0)
                        return false;
                }

                //if the maxwait exceeded 10 seconds then we will stop increasing the maxWait time and keep it 10 seconds, otherwise keep doubling it
                maxWait = maxWait >= waitTimeCeiling ? waitTimeCeiling : Math.Min(maxWait << 1, waitTimeCeiling);
            }

            //if we exited the loop because the observed phase doesn't match the current phase, then we have to spin to mske sure
            //the event is set or the next phase is finished
            WaitCurrentPhase(currentPhaseEvent, observedPhase);

            return true;
        }