Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32.SafeHandles;

internal static partial class Interop
Expand All @@ -15,19 +15,18 @@ internal static partial class Sys
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_IsMemfdSupported", SetLastError = true)]
private static partial int MemfdSupportedImpl();

private static volatile sbyte s_memfdSupported;
private static volatile NullableBool s_memfdSupported;

internal static bool IsMemfdSupported
{
get
{
sbyte memfdSupported = s_memfdSupported;
if (memfdSupported == 0)
NullableBool memfdSupported = s_memfdSupported;
if (memfdSupported == NullableBool.Undefined)
{
Interlocked.CompareExchange(ref s_memfdSupported, (sbyte)(MemfdSupportedImpl() == 1 ? 1 : -1), 0);
memfdSupported = s_memfdSupported;
s_memfdSupported = memfdSupported = MemfdSupportedImpl() == 1 ? NullableBool.True : NullableBool.False;
}
return memfdSupported > 0;
return memfdSupported == NullableBool.True;
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/Common/src/System/Console/ConsoleUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ namespace System
internal static partial class ConsoleUtils
{
/// <summary>Whether to output ansi color strings.</summary>
private static volatile int s_emitAnsiColorCodes = -1;
private static volatile NullableBool s_emitAnsiColorCodes;

/// <summary>Get whether to emit ANSI color codes.</summary>
public static bool EmitAnsiColorCodes
{
get
{
// The flag starts at -1. If it's no longer -1, it's 0 or 1 to represent false or true.
int emitAnsiColorCodes = s_emitAnsiColorCodes;
if (emitAnsiColorCodes != -1)
// The flag starts at Undefined. If it's no longer Undefined, it's False or True.
NullableBool emitAnsiColorCodes = s_emitAnsiColorCodes;
if (emitAnsiColorCodes != NullableBool.Undefined)
{
return Convert.ToBoolean(emitAnsiColorCodes);
return emitAnsiColorCodes == NullableBool.True;
}

// We've not yet computed whether to emit codes or not. Do so now. We may race with
Expand All @@ -43,7 +43,7 @@ public static bool EmitAnsiColorCodes
}

// Store and return the computed answer.
s_emitAnsiColorCodes = Convert.ToInt32(enabled);
s_emitAnsiColorCodes = enabled ? NullableBool.True : NullableBool.False;
return enabled;
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/libraries/Common/src/System/NullableBool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System
{
/// <summary>
/// Used instead of bool? for thread-safe state because <see cref="Nullable{Boolean}"/> is not guaranteed to be read or written atomically.
/// </summary>
internal enum NullableBool : sbyte
{
Undefined = 0,
False = -1,
True = 1,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GetConsoleMode.cs" Link="Common\Interop\Windows\Interop.GetConsoleMode.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GetStdHandle.cs" Link="Common\Interop\Windows\Interop.GetStdHandle.cs" />
<Compile Include="$(CommonPath)System\Console\ConsoleUtils.cs" Link="Common\System\Console\ConsoleUtils.cs" />
<Compile Include="$(CommonPath)System\NullableBool.cs" Link="Common\System\NullableBool.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/System.Console/src/System.Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@
<Compile Include="System\TerminalFormatStrings.cs" />
<Compile Include="$(CommonPath)System\Console\ConsoleUtils.cs"
Link="Common\System\Console\ConsoleUtils.cs" />
<Compile Include="$(CommonPath)System\NullableBool.cs"
Link="Common\System\NullableBool.cs" />
<Compile Include="System\TermInfo.cs" />
<Compile Include="System\TermInfo.WellKnownStrings.cs" />
<Compile Include="System\TermInfo.Database.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@
<Compile Include="System\Diagnostics\Process.Linux.cs" />
<Compile Include="System\Diagnostics\ProcessManager.Linux.cs" />
<Compile Include="System\Diagnostics\ProcessThread.Linux.cs" />
<Compile Include="$(CommonPath)System\NullableBool.cs"
Link="Common\System\NullableBool.cs" />
<Compile Include="$(CommonPath)Interop\Linux\cgroups\Interop.cgroups.cs"
Link="Common\Interop\Linux\Interop.cgroups.cs" />
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.MountPoints.FormatInfo.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace System.Diagnostics
{
internal static partial class ProcessManager
{
private static volatile int _procMatchesPidNamespace;
private static volatile NullableBool _procMatchesPidNamespace;

/// <summary>Gets the IDs of all processes on the current machine.</summary>
public static int[] GetProcessIds() => new List<int>(EnumerateProcessIds()).ToArray();
Expand Down Expand Up @@ -266,11 +266,7 @@ internal static bool ProcMatchesPidNamespace
{
get
{
// _procMatchesPidNamespace is set to:
// - 0: when uninitialized,
// - 1: '/proc' and the process pid namespace match,
// - 2: when they don't match.
if (_procMatchesPidNamespace == 0)
if (_procMatchesPidNamespace == NullableBool.Undefined)
{
// '/proc/self' is a symlink to the pid used by '/proc' for the current process.
// We compare it with the pid of the current process to see if the '/proc' and pid namespace match up.
Expand All @@ -282,9 +278,9 @@ internal static bool ProcMatchesPidNamespace
}
Debug.Assert(procSelfPid.HasValue);

_procMatchesPidNamespace = !procSelfPid.HasValue || procSelfPid == Environment.ProcessId ? 1 : 2;
_procMatchesPidNamespace = !procSelfPid.HasValue || procSelfPid == Environment.ProcessId ? NullableBool.True : NullableBool.False;
}
return _procMatchesPidNamespace == 1;
return _procMatchesPidNamespace == NullableBool.True;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@
Link="Common\Interop\Unix\Interop.MAdvise.cs" />
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.ShmOpen.cs"
Link="Common\Interop\Unix\Interop.ShmOpen.cs" />
<Compile Include="$(CommonPath)System\NullableBool.cs"
Link="Common\System\NullableBool.cs" />
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.MemfdCreate.cs"
Link="Common\Interop\Unix\Interop.MemfdCreate.cs" />
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.Unlink.cs"
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@
Link="Common\System\Text\SimpleRegex.cs" />
<Compile Include="$(CommonPath)System\HexConverter.cs"
Link="Common\System\HexConverter.cs" />
<Compile Include="$(CommonPath)System\NullableBool.cs"
Link="Common\System\NullableBool.cs" />
<Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs"
Link="Common\System\Net\ArrayBuffer.cs"/>
<Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,32 @@ internal static partial class AuthenticationHelper
private const string UsePortInSpnCtxSwitch = "System.Net.Http.UsePortInSpn";
private const string UsePortInSpnEnvironmentVariable = "DOTNET_SYSTEM_NET_HTTP_USEPORTINSPN";

private static volatile int s_usePortInSpn = -1;
private static volatile NullableBool s_usePortInSpn;

private static bool UsePortInSpn
{
get
{
int usePortInSpn = s_usePortInSpn;
if (usePortInSpn != -1)
NullableBool usePortInSpn = s_usePortInSpn;
if (usePortInSpn != NullableBool.Undefined)
{
return usePortInSpn != 0;
return usePortInSpn == NullableBool.True;
}

// First check for the AppContext switch, giving it priority over the environment variable.
if (AppContext.TryGetSwitch(UsePortInSpnCtxSwitch, out bool value))
{
s_usePortInSpn = value ? 1 : 0;
s_usePortInSpn = value ? NullableBool.True : NullableBool.False;
}
else
{
// AppContext switch wasn't used. Check the environment variable.
s_usePortInSpn =
Environment.GetEnvironmentVariable(UsePortInSpnEnvironmentVariable) is string envVar &&
(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? 1 : 0;
(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? NullableBool.True : NullableBool.False;
}

return s_usePortInSpn != 0;
return s_usePortInSpn == NullableBool.True;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
<Compile Include="System\Net\NameResolutionPal.Windows.cs" />
<Compile Include="$(CommonPath)System\NullableBool.cs"
Link="Common\System\NullableBool.cs" />
<!-- Debug only -->
<Compile Include="$(CommonPath)System\Net\DebugSafeHandle.cs"
Link="Common\System\Net\DebugSafeHandle.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,17 @@ namespace System.Net
{
internal static partial class NameResolutionPal
{
private static volatile int s_getAddrInfoExSupported;
private static volatile NullableBool s_getAddrInfoExSupported;

public static bool SupportsGetAddrInfoAsync
{
get
{
int supported = s_getAddrInfoExSupported;
if (supported == 0)
if (s_getAddrInfoExSupported == NullableBool.Undefined)
{
Initialize();
supported = s_getAddrInfoExSupported;
}
return supported == 1;
return s_getAddrInfoExSupported == NullableBool.True;

static void Initialize()
{
Expand All @@ -39,7 +37,7 @@ static void Initialize()
// We can't just check that 'GetAddrInfoEx' exists, because it existed before supporting overlapped.
// The existence of 'GetAddrInfoExCancel' indicates that overlapped is supported.
bool supported = NativeLibrary.TryGetExport(libHandle, Interop.Winsock.GetAddrInfoExCancelFunctionName, out _);
Interlocked.CompareExchange(ref s_getAddrInfoExSupported, supported ? 1 : -1, 0);
s_getAddrInfoExSupported = supported ? NullableBool.True : NullableBool.False;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
<ItemGroup Condition=" '$(TargetPlatformIdentifier)' == 'windows' ">
<Compile Include="..\..\src\System\Net\NameResolutionPal.Windows.cs"
Link="ProductionCode\System\Net\NameResolutionPal.Windows.cs" />
<Compile Include="$(CommonPath)System\NullableBool.cs"
Link="Common\System\NullableBool.cs" />
<Compile Include="$(CommonPath)System\Net\InternalException.cs"
Link="Common\System\Net\InternalException.cs" />
<Compile Include="$(CommonPath)System\Net\SocketProtocolSupportPal.Windows.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@
Link="Common\System\Net\NegotiationInfoClass.cs" />
<Compile Include="$(CommonPath)System\HexConverter.cs"
Link="Common\System\HexConverter.cs" />
<Compile Include="$(CommonPath)System\NullableBool.cs"
Link="Common\System\NullableBool.cs" />
<Compile Include="$(CommonPath)Interop\Windows\SChannel\Interop.SECURITY_STATUS.cs"
Link="Common\Interop\Windows\SChannel\Interop.SECURITY_STATUS.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,60 +21,60 @@ public partial class SslStream
private const string EnableServerAiaDownloadsCtxSwitch = "System.Net.Security.EnableServerAiaDownloads";
private const string EnableServerAiaDownloadsEnvironmentVariable = "DOTNET_SYSTEM_NET_SECURITY_ENABLESERVERAIADOWNLOADS";

private static volatile int s_disableTlsResume = -1;
private static volatile int s_enableServerAiaDownloads = -1;
private static volatile NullableBool s_disableTlsResume;
private static volatile NullableBool s_enableServerAiaDownloads;

internal static bool DisableTlsResume
{
get
{
int disableTlsResume = s_disableTlsResume;
if (disableTlsResume != -1)
NullableBool disableTlsResume = s_disableTlsResume;
if (disableTlsResume != NullableBool.Undefined)
{
return disableTlsResume != 0;
return disableTlsResume == NullableBool.True;
}

// First check for the AppContext switch, giving it priority over the environment variable.
if (AppContext.TryGetSwitch(DisableTlsResumeCtxSwitch, out bool value))
{
s_disableTlsResume = value ? 1 : 0;
s_disableTlsResume = value ? NullableBool.True : NullableBool.False;
}
else
{
// AppContext switch wasn't used. Check the environment variable.
s_disableTlsResume =
Environment.GetEnvironmentVariable(DisableTlsResumeEnvironmentVariable) is string envVar &&
(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? 1 : 0;
(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? NullableBool.True : NullableBool.False;
}

return s_disableTlsResume != 0;
return s_disableTlsResume == NullableBool.True;
}
}

internal static bool EnableServerAiaDownloads
{
get
{
int enableServerAiaDownloads = s_enableServerAiaDownloads;
if (enableServerAiaDownloads != -1)
NullableBool enableServerAiaDownloads = s_enableServerAiaDownloads;
if (enableServerAiaDownloads != NullableBool.Undefined)
{
return enableServerAiaDownloads != 0;
return enableServerAiaDownloads == NullableBool.True;
}

// First check for the AppContext switch, giving it priority over the environment variable.
if (AppContext.TryGetSwitch(EnableServerAiaDownloadsCtxSwitch, out bool value))
{
s_enableServerAiaDownloads = value ? 1 : 0;
s_enableServerAiaDownloads = value ? NullableBool.True : NullableBool.False;
}
else
{
// AppContext switch wasn't used. Check the environment variable.
s_enableServerAiaDownloads =
Environment.GetEnvironmentVariable(EnableServerAiaDownloadsEnvironmentVariable) is string envVar &&
(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? 1 : 0;
(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? NullableBool.True : NullableBool.False;
}

return s_enableServerAiaDownloads != 0;
return s_enableServerAiaDownloads == NullableBool.True;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,5 @@ internal long GetFileLength()
FileStreamHelpers.CheckFileCall(result, Path);
return status.Size;
}

private enum NullableBool
{
Undefined = 0,
False = -1,
True = 1
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,9 @@
<Compile Include="$(CommonPath)System\HexConverter.cs">
<Link>Common\System\HexConverter.cs</Link>
</Compile>
<Compile Include="$(CommonPath)System\NullableBool.cs">
<Link>Common\System\NullableBool.cs</Link>
</Compile>
<Compile Include="$(CommonPath)System\HResults.cs">
<Link>Common\System\HResults.cs</Link>
</Compile>
Expand Down
10 changes: 5 additions & 5 deletions src/libraries/System.Private.CoreLib/src/System/Environment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public readonly struct ProcessCpuUsage
internal static bool IsSingleProcessor => RuntimeFeature.IsMultithreadingSupported ? ProcessorCount == 1 : true;
public static int ProcessorCount { get; } = RuntimeFeature.IsMultithreadingSupported ? GetProcessorCount() : 1;

private static volatile sbyte s_privilegedProcess;
private static volatile NullableBool s_privilegedProcess;

/// <summary>
/// Gets whether the current process is authorized to perform security-relevant functions.
Expand All @@ -50,12 +50,12 @@ public static bool IsPrivilegedProcess
{
get
{
sbyte privilegedProcess = s_privilegedProcess;
if (privilegedProcess == 0)
NullableBool privilegedProcess = s_privilegedProcess;
if (privilegedProcess == NullableBool.Undefined)
{
s_privilegedProcess = privilegedProcess = IsPrivilegedProcessCore() ? (sbyte)1 : (sbyte)-1;
s_privilegedProcess = privilegedProcess = IsPrivilegedProcessCore() ? NullableBool.True : NullableBool.False;
}
return privilegedProcess > 0;
return privilegedProcess == NullableBool.True;
}
}

Expand Down
Loading
Loading