From 10f72f160bdd8a8a0385a07c3ccc63cc9a85d7f5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 31 May 2019 13:25:15 -0700 Subject: [PATCH] [master] Update dependencies from dotnet/coreclr (dotnet/corefx#38099) * Update dependencies from https://github.com/dotnet/coreclr build 20190530.2 - Microsoft.NET.Sdk.IL - 3.0.0-preview6.19280.2 - Microsoft.NETCore.ILAsm - 3.0.0-preview6.19280.2 - Microsoft.NETCore.Runtime.CoreCLR - 3.0.0-preview6.19280.2 * Expose, test, and use Environment.TickCount64 * Back out change to WinInetProxyHelper.cs Commit migrated from https://github.com/dotnet/corefx/commit/06f25eaa8592b49c65373d0cdcbdac9a4bdf0f35 --- .../src/System/Net/Http/WinInetProxyHelper.cs | 2 +- .../Net/Http/SocketsHttpHandler/Http2Connection.cs | 12 ++++++------ .../Net/Http/SocketsHttpHandler/HttpConnectionBase.cs | 8 ++++---- .../Net/Http/SocketsHttpHandler/HttpConnectionPool.cs | 18 +++++++++--------- .../Http/SocketsHttpHandler/HttpConnectionSettings.cs | 15 ++------------- .../ref/System.Runtime.Extensions.cs | 1 + .../tests/System/Environment.TickCount.cs | 18 +++++++++++++++++- 7 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinInetProxyHelper.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinInetProxyHelper.cs index a56bea1..4a26aa8 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinInetProxyHelper.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinInetProxyHelper.cs @@ -179,4 +179,4 @@ namespace System.Net.Http return useProxy; } } -} +} \ No newline at end of file diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index b85233f..8b7b95b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -41,7 +41,7 @@ namespace System.Net.Http private int _initialWindowSize; private int _maxConcurrentStreams; private int _pendingWindowUpdate; - private int _idleSinceTickCount; + private long _idleSinceTickCount; private int _pendingWriters; private bool _disposed; @@ -1138,7 +1138,7 @@ namespace System.Net.Http } /// Gets whether the connection exceeded any of the connection limits. - /// The current tick count. Passed in to amortize the cost of calling Environment.TickCount. + /// The current tick count. Passed in to amortize the cost of calling Environment.TickCount64. /// How long a connection can be open to be considered reusable. /// How long a connection can have been idle in the pool to be considered reusable. /// @@ -1149,7 +1149,7 @@ namespace System.Net.Http /// the nature of connection pooling. /// - public bool IsExpired(int nowTicks, + public bool IsExpired(long nowTicks, TimeSpan connectionLifetime, TimeSpan connectionIdleTimeout) @@ -1162,9 +1162,9 @@ namespace System.Net.Http // Check idle timeout when there are not pending requests for a while. if ((connectionIdleTimeout != Timeout.InfiniteTimeSpan) && (_httpStreams.Count == 0) && - ((uint)(nowTicks - _idleSinceTickCount) > connectionIdleTimeout.TotalMilliseconds)) + ((nowTicks - _idleSinceTickCount) > connectionIdleTimeout.TotalMilliseconds)) { - if (NetEventSource.IsEnabled) Trace($"Connection no longer usable. Idle {TimeSpan.FromMilliseconds((uint)(nowTicks - _idleSinceTickCount))} > {connectionIdleTimeout}."); + if (NetEventSource.IsEnabled) Trace($"Connection no longer usable. Idle {TimeSpan.FromMilliseconds((nowTicks - _idleSinceTickCount))} > {connectionIdleTimeout}."); return true; } @@ -1448,7 +1448,7 @@ namespace System.Net.Http if (_httpStreams.Count == 0) { // If this was last pending request, get timestamp so we can monitor idle time. - _idleSinceTickCount = Environment.TickCount; + _idleSinceTickCount = Environment.TickCount64; } if (_disposed) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs index 2e6d432..24deb84 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs @@ -12,16 +12,16 @@ namespace System.Net.Http public abstract Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken); internal abstract void Trace(string message, string memberName = null); - private int CreationTickCount { get; } = Environment.TickCount; + private long CreationTickCount { get; } = Environment.TickCount64; // Check if lifetime expired on connection. - public bool LifetimeExpired(int nowTicks, TimeSpan lifetime) + public bool LifetimeExpired(long nowTicks, TimeSpan lifetime) { bool expired = lifetime != Timeout.InfiniteTimeSpan && - (lifetime == TimeSpan.Zero || (uint)(nowTicks - CreationTickCount) > lifetime.TotalMilliseconds); + (lifetime == TimeSpan.Zero || (nowTicks - CreationTickCount) > lifetime.TotalMilliseconds); - if (expired && NetEventSource.IsEnabled) Trace($"Connection no longer usable. Alive {TimeSpan.FromMilliseconds((uint)(nowTicks - CreationTickCount))} > {lifetime}."); + if (expired && NetEventSource.IsEnabled) Trace($"Connection no longer usable. Alive {TimeSpan.FromMilliseconds((nowTicks - CreationTickCount))} > {lifetime}."); return expired; } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs index ba60505..624de5c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs @@ -229,7 +229,7 @@ namespace System.Net.Http TimeSpan pooledConnectionLifetime = _poolManager.Settings._pooledConnectionLifetime; TimeSpan pooledConnectionIdleTimeout = _poolManager.Settings._pooledConnectionIdleTimeout; - int nowTicks = Environment.TickCount; + long nowTicks = Environment.TickCount64; List list = _idleConnections; // Try to find a usable cached connection. @@ -340,7 +340,7 @@ namespace System.Net.Http if (http2Connection != null) { TimeSpan pooledConnectionLifetime = _poolManager.Settings._pooledConnectionLifetime; - if (http2Connection.LifetimeExpired(Environment.TickCount, pooledConnectionLifetime)) + if (http2Connection.LifetimeExpired(Environment.TickCount64, pooledConnectionLifetime)) { // Connection expired. http2Connection.Dispose(); @@ -797,7 +797,7 @@ namespace System.Net.Http /// The connection to return. public void ReturnConnection(HttpConnection connection) { - bool lifetimeExpired = connection.LifetimeExpired(Environment.TickCount, _poolManager.Settings._pooledConnectionLifetime); + bool lifetimeExpired = connection.LifetimeExpired(Environment.TickCount64, _poolManager.Settings._pooledConnectionLifetime); if (!lifetimeExpired) { @@ -915,7 +915,7 @@ namespace System.Net.Http // Get the current time. This is compared against each connection's last returned // time to determine whether a connection is too old and should be closed. - int nowTicks = Environment.TickCount; + long nowTicks = Environment.TickCount64; Http2Connection http2Connection = _http2Connection; if (http2Connection != null) @@ -1039,7 +1039,7 @@ namespace System.Net.Http /// The cached connection. internal readonly HttpConnection _connection; /// The last tick count at which the connection was used. - internal readonly int _returnedTickCount; + internal readonly long _returnedTickCount; /// Initializes the cached connection and its associated metadata. /// The connection. @@ -1047,7 +1047,7 @@ namespace System.Net.Http { Debug.Assert(connection != null); _connection = connection; - _returnedTickCount = Environment.TickCount; + _returnedTickCount = Environment.TickCount64; } /// Gets whether the connection is currently usable. @@ -1062,16 +1062,16 @@ namespace System.Net.Http /// the nature of connection pooling. /// public bool IsUsable( - int nowTicks, + long nowTicks, TimeSpan pooledConnectionLifetime, TimeSpan pooledConnectionIdleTimeout, bool poll = false) { // Validate that the connection hasn't been idle in the pool for longer than is allowed. if ((pooledConnectionIdleTimeout != Timeout.InfiniteTimeSpan) && - ((uint)(nowTicks - _returnedTickCount) > pooledConnectionIdleTimeout.TotalMilliseconds)) + ((nowTicks - _returnedTickCount) > pooledConnectionIdleTimeout.TotalMilliseconds)) { - if (NetEventSource.IsEnabled) _connection.Trace($"Connection no longer usable. Idle {TimeSpan.FromMilliseconds((uint)(nowTicks - _returnedTickCount))} > {pooledConnectionIdleTimeout}."); + if (NetEventSource.IsEnabled) _connection.Trace($"Connection no longer usable. Idle {TimeSpan.FromMilliseconds((nowTicks - _returnedTickCount))} > {pooledConnectionIdleTimeout}."); return false; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index 3fe4076..f678873 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -64,17 +64,6 @@ namespace System.Net.Http _cookieContainer = new CookieContainer(); } - // The implementation uses Environment.TickCount to track connection lifetimes, as Environment.TickCount - // is measurable faster than DateTime.UtcNow / Stopwatch.GetTimestamp, and we do it at least once per request. - // However, besides its lower resolution (which is fine for SocketHttpHandler's needs), due to being based on - // an Int32 rather than Int64, the difference between two tick counts is at most ~49 days. This means that - // specifying a connection idle or lifetime of greater than 49 days would cause it to never be reached. The - // chances of a connection being open anywhere near that long is close to zero, as is the chance that someone - // would choose to specify such a long timeout, but regardless, we avoid issues by capping the timeouts. - TimeSpan timeLimit = TimeSpan.FromDays(40); // something super long but significantly less than the 49 day limit - TimeSpan pooledConnectionLifetime = _pooledConnectionLifetime < timeLimit ? _pooledConnectionLifetime : timeLimit; - TimeSpan pooledConnectionIdleTimeout = _pooledConnectionIdleTimeout < timeLimit ? _pooledConnectionIdleTimeout : timeLimit; - return new HttpConnectionSettings() { _allowAutoRedirect = _allowAutoRedirect, @@ -90,8 +79,8 @@ namespace System.Net.Http _maxResponseDrainSize = _maxResponseDrainSize, _maxResponseDrainTime = _maxResponseDrainTime, _maxResponseHeadersLength = _maxResponseHeadersLength, - _pooledConnectionLifetime = pooledConnectionLifetime, - _pooledConnectionIdleTimeout = pooledConnectionIdleTimeout, + _pooledConnectionLifetime = _pooledConnectionLifetime, + _pooledConnectionIdleTimeout = _pooledConnectionIdleTimeout, _preAuthenticate = _preAuthenticate, _properties = _properties, _proxy = _proxy, diff --git a/src/libraries/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs b/src/libraries/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs index ca2b6f4..7688ffe 100644 --- a/src/libraries/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs +++ b/src/libraries/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs @@ -670,6 +670,7 @@ namespace System public static string SystemDirectory { get { throw null; } } public static int SystemPageSize { get { throw null; } } public static int TickCount { get { throw null; } } + public static long TickCount64 { get { throw null; } } public static string UserDomainName { get { throw null; } } public static bool UserInteractive { get { throw null; } } public static string UserName { get { throw null; } } diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.TickCount.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.TickCount.cs index ccd28e9..b2e8f37 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.TickCount.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.TickCount.cs @@ -15,7 +15,7 @@ namespace System.Tests public void TickCountTest() { int start = Environment.TickCount; - HashSet times = new HashSet(); + var times = new HashSet(); Func test = () => { int time = Environment.TickCount; @@ -26,5 +26,21 @@ namespace System.Tests SpinWait.SpinUntil(test, TimeSpan.FromSeconds(1)) || test(), $"TickCount did not increase after one second. start: {start}, values tested: {string.Join(", ", times.ToArray())}."); } + + [Fact] + public void TickCount64Test() + { + long start = Environment.TickCount64; + var times = new HashSet(); + Func test = () => + { + long time = Environment.TickCount64; + times.Add(time); + return time - start > 0; + }; + Assert.True( + SpinWait.SpinUntil(test, TimeSpan.FromSeconds(1)) || test(), + $"TickCount did not increase after one second. start: {start}, values tested: {string.Join(", ", times.ToArray())}."); + } } } -- 2.7.4