From 2adb6ff955ac9bc84d0ff7556536acd3aff3a138 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 7 Oct 2016 00:59:31 +0100 Subject: [PATCH] Interlocked.Read -> Volatile.Read --- .../Internal/Http/Connection.cs | 2 +- .../Internal/Http/DateHeaderValueManager.cs | 3 ++- .../Internal/Networking/PlatformApis.cs | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs index 9c9e225a9f..d48bc08944 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs @@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http // Called on Libuv thread public void Tick(long timestamp) { - if (timestamp > Interlocked.Read(ref _timeoutTimestamp)) + if (timestamp > PlatformApis.VolatileRead(ref _timeoutTimestamp)) { ConnectionControl.CancelTimeout(); diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/DateHeaderValueManager.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/DateHeaderValueManager.cs index b824fb606d..cb36c22d34 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/DateHeaderValueManager.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/DateHeaderValueManager.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading; using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure; using Microsoft.Net.Http.Headers; +using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking; namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http { @@ -158,7 +159,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http } // No requests since the last timer tick, we need to check if we're beyond the idle threshold - if ((now.Ticks - Interlocked.Read(ref _lastRequestSeenTicks)) >= _timeWithoutRequestsUntilIdle.Ticks) + if ((now.Ticks - PlatformApis.VolatileRead(ref _lastRequestSeenTicks)) >= _timeWithoutRequestsUntilIdle.Ticks) { // No requests since idle threshold so stop the timer if it's still running StopTimer(); diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Networking/PlatformApis.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Networking/PlatformApis.cs index e81974adb2..6cd2341815 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Networking/PlatformApis.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Networking/PlatformApis.cs @@ -1,7 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Networking { @@ -16,5 +19,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Networking public static bool IsWindows { get; } public static bool IsDarwin { get; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long VolatileRead(ref long value) + { + if (IntPtr.Size == 8) + { + return Volatile.Read(ref value); + } + else + { + // Avoid torn long reads on 32-bit + return Interlocked.Read(ref value); + } + } } }