You've already forked linux-packaging-mono
Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
134
external/referencesource/System.ServiceModel.Internals/System/Runtime/BackoffTimeoutHelper.cs
vendored
Normal file
134
external/referencesource/System.ServiceModel.Internals/System/Runtime/BackoffTimeoutHelper.cs
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Runtime
|
||||
{
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
sealed class BackoffTimeoutHelper
|
||||
{
|
||||
readonly static int maxSkewMilliseconds = (int)(IOThreadTimer.SystemTimeResolutionTicks / TimeSpan.TicksPerMillisecond);
|
||||
readonly static long maxDriftTicks = IOThreadTimer.SystemTimeResolutionTicks * 2;
|
||||
readonly static TimeSpan defaultInitialWaitTime = TimeSpan.FromMilliseconds(1);
|
||||
readonly static TimeSpan defaultMaxWaitTime = TimeSpan.FromMinutes(1);
|
||||
|
||||
DateTime deadline;
|
||||
TimeSpan maxWaitTime;
|
||||
TimeSpan waitTime;
|
||||
IOThreadTimer backoffTimer;
|
||||
Action<object> backoffCallback;
|
||||
object backoffState;
|
||||
Random random;
|
||||
TimeSpan originalTimeout;
|
||||
|
||||
internal BackoffTimeoutHelper(TimeSpan timeout)
|
||||
: this(timeout, BackoffTimeoutHelper.defaultMaxWaitTime)
|
||||
{
|
||||
}
|
||||
|
||||
internal BackoffTimeoutHelper(TimeSpan timeout, TimeSpan maxWaitTime)
|
||||
: this(timeout, maxWaitTime, BackoffTimeoutHelper.defaultInitialWaitTime)
|
||||
{
|
||||
}
|
||||
|
||||
internal BackoffTimeoutHelper(TimeSpan timeout, TimeSpan maxWaitTime, TimeSpan initialWaitTime)
|
||||
{
|
||||
this.random = new Random(GetHashCode());
|
||||
this.maxWaitTime = maxWaitTime;
|
||||
this.originalTimeout = timeout;
|
||||
Reset(timeout, initialWaitTime);
|
||||
}
|
||||
|
||||
public TimeSpan OriginalTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.originalTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset(TimeSpan timeout, TimeSpan initialWaitTime)
|
||||
{
|
||||
if (timeout == TimeSpan.MaxValue)
|
||||
{
|
||||
this.deadline = DateTime.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.deadline = DateTime.UtcNow + timeout;
|
||||
}
|
||||
this.waitTime = initialWaitTime;
|
||||
}
|
||||
|
||||
public bool IsExpired()
|
||||
{
|
||||
if (this.deadline == DateTime.MaxValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (DateTime.UtcNow >= this.deadline);
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitAndBackoff(Action<object> callback, object state)
|
||||
{
|
||||
if (this.backoffCallback != callback || this.backoffState != state)
|
||||
{
|
||||
if (this.backoffTimer != null)
|
||||
{
|
||||
this.backoffTimer.Cancel();
|
||||
}
|
||||
this.backoffCallback = callback;
|
||||
this.backoffState = state;
|
||||
this.backoffTimer = new IOThreadTimer(callback, state, false, BackoffTimeoutHelper.maxSkewMilliseconds);
|
||||
}
|
||||
|
||||
TimeSpan backoffTime = WaitTimeWithDrift();
|
||||
Backoff();
|
||||
this.backoffTimer.Set(backoffTime);
|
||||
}
|
||||
|
||||
public void WaitAndBackoff()
|
||||
{
|
||||
Thread.Sleep(WaitTimeWithDrift());
|
||||
Backoff();
|
||||
}
|
||||
|
||||
TimeSpan WaitTimeWithDrift()
|
||||
{
|
||||
return Ticks.ToTimeSpan(Math.Max(
|
||||
Ticks.FromTimeSpan(BackoffTimeoutHelper.defaultInitialWaitTime),
|
||||
Ticks.Add(Ticks.FromTimeSpan(this.waitTime),
|
||||
(long)(uint)this.random.Next() % (2 * BackoffTimeoutHelper.maxDriftTicks + 1) - BackoffTimeoutHelper.maxDriftTicks)));
|
||||
}
|
||||
|
||||
void Backoff()
|
||||
{
|
||||
if (waitTime.Ticks >= (maxWaitTime.Ticks / 2))
|
||||
{
|
||||
waitTime = maxWaitTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
waitTime = TimeSpan.FromTicks(waitTime.Ticks * 2);
|
||||
}
|
||||
|
||||
if (this.deadline != DateTime.MaxValue)
|
||||
{
|
||||
TimeSpan remainingTime = this.deadline - DateTime.UtcNow;
|
||||
if (this.waitTime > remainingTime)
|
||||
{
|
||||
this.waitTime = remainingTime;
|
||||
if (this.waitTime < TimeSpan.Zero)
|
||||
{
|
||||
this.waitTime = TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user