From fb13f3c7d83c233126121e557cd96d7ea5e4b22b Mon Sep 17 00:00:00 2001 From: Jaideep Pyne <25899506+jaideeppyne@users.noreply.github.com> Date: Sat, 8 Aug 2026 14:58:30 +0530 Subject: [PATCH] Fix PerformanceCounterLib cache races Capture initialized cache tables before returning so concurrent invalidation cannot turn a successful lookup into null. Synchronize shared library-table enumeration with creation and replacement. Fix #90803 --- .../Diagnostics/PerformanceCounterLib.cs | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs index 34f317c812be5f..c47f75f065535d 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs @@ -124,7 +124,8 @@ internal Hashtable CategoryTable { get { - if (_categoryTable == null) + Hashtable categoryTable = _categoryTable; + if (categoryTable == null) { lock (_categoryTableLock) { @@ -194,10 +195,12 @@ internal Hashtable CategoryTable _categoryTable = tempCategoryTable; } + + categoryTable = _categoryTable; } } - return _categoryTable; + return categoryTable; } } @@ -205,15 +208,16 @@ internal Hashtable HelpTable { get { - if (_helpTable == null) + Hashtable helpTable = _helpTable; + if (helpTable == null) { lock (_helpTableLock) { - _helpTable ??= GetStringTable(true); + helpTable = _helpTable ??= GetStringTable(true); } } - return _helpTable; + return helpTable; } } @@ -246,15 +250,16 @@ internal Hashtable NameTable { get { - if (_nameTable == null) + Hashtable nameTable = _nameTable; + if (nameTable == null) { lock (_nameTableLock) { - _nameTable ??= GetStringTable(false); + nameTable = _nameTable ??= GetStringTable(false); } } - return _nameTable; + return nameTable; } } @@ -329,10 +334,13 @@ internal static void CloseAllLibraries() internal static void CloseAllTables() { - if (s_libraryTable != null) + lock (InternalSyncObject) { - foreach (PerformanceCounterLib library in s_libraryTable.Values) - library.CloseTables(); + if (s_libraryTable != null) + { + foreach (PerformanceCounterLib library in s_libraryTable.Values) + library.CloseTables(); + } } }