Skip to content

Commit e0eef4f

Browse files
committed
Merge remote-tracking branch 'dotnet/main' into prefer-vector-width-3
2 parents e16eed8 + e5c3811 commit e0eef4f

28 files changed

+300
-145
lines changed

src/coreclr/inc/clrconfigvalues.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ CONFIG_DWORD_INFO(INTERNAL_OSR_HighId, W("OSR_HighId"), 10000000, "High end of e
614614
RETAIL_CONFIG_STRING_INFO(INTERNAL_PGODataPath, W("PGODataPath"), "Read/Write PGO data from/to the indicated file.")
615615
RETAIL_CONFIG_DWORD_INFO(INTERNAL_ReadPGOData, W("ReadPGOData"), 0, "Read PGO data")
616616
RETAIL_CONFIG_DWORD_INFO(INTERNAL_WritePGOData, W("WritePGOData"), 0, "Write PGO data")
617-
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TieredPGO, W("TieredPGO"), 0, "Instrument Tier0 code and make counts available to Tier1")
617+
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TieredPGO, W("TieredPGO"), 1, "Instrument Tier0 code and make counts available to Tier1")
618618

619619
// TieredPGO_InstrumentOnlyHotCode values:
620620
//

src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public static IConfigurationBuilder SetFileProvider(this IConfigurationBuilder b
2929
return builder;
3030
}
3131

32+
internal static IFileProvider? GetUserDefinedFileProvider(this IConfigurationBuilder builder)
33+
=> builder.Properties.TryGetValue(FileProviderKey, out object? provider) ? (IFileProvider)provider : null;
34+
3235
/// <summary>
3336
/// Gets the default <see cref="IFileProvider"/> to be used for file-based providers.
3437
/// </summary>
@@ -38,12 +41,7 @@ public static IFileProvider GetFileProvider(this IConfigurationBuilder builder)
3841
{
3942
ThrowHelper.ThrowIfNull(builder);
4043

41-
if (builder.Properties.TryGetValue(FileProviderKey, out object? provider))
42-
{
43-
return (IFileProvider)provider;
44-
}
45-
46-
return new PhysicalFileProvider(AppContext.BaseDirectory ?? string.Empty);
44+
return GetUserDefinedFileProvider(builder) ?? new PhysicalFileProvider(AppContext.BaseDirectory ?? string.Empty);
4745
}
4846

4947
/// <summary>

src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ private void HandleException(ExceptionDispatchInfo info)
162162
protected virtual void Dispose(bool disposing)
163163
{
164164
_changeTokenRegistration?.Dispose();
165+
166+
if (Source.OwnsFileProvider)
167+
{
168+
(Source.FileProvider as IDisposable)?.Dispose();
169+
}
165170
}
166171
}
167172
}

src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ public abstract class FileConfigurationSource : IConfigurationSource
1818
/// </summary>
1919
public IFileProvider? FileProvider { get; set; }
2020

21+
/// <summary>
22+
/// Set to true when <see cref="FileProvider"/> was not provided by user and can be safely disposed.
23+
/// </summary>
24+
internal bool OwnsFileProvider { get; private set; }
25+
2126
/// <summary>
2227
/// The path to the file.
2328
/// </summary>
@@ -58,6 +63,11 @@ public abstract class FileConfigurationSource : IConfigurationSource
5863
/// <param name="builder">The <see cref="IConfigurationBuilder"/>.</param>
5964
public void EnsureDefaults(IConfigurationBuilder builder)
6065
{
66+
if (FileProvider is null && builder.GetUserDefinedFileProvider() is null)
67+
{
68+
OwnsFileProvider = true;
69+
}
70+
6171
FileProvider ??= builder.GetFileProvider();
6272
OnLoadException ??= builder.GetFileLoadExceptionHandler();
6373
}
@@ -81,6 +91,7 @@ public void ResolveFileProvider()
8191
}
8292
if (Directory.Exists(directory))
8393
{
94+
OwnsFileProvider = true;
8495
FileProvider = new PhysicalFileProvider(directory);
8596
Path = pathToFile;
8697
}

src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
using System;
55
using System.Globalization;
66
using System.IO;
7+
using System.Linq;
78
using Microsoft.Extensions.Configuration.Json;
89
using Microsoft.Extensions.Configuration.Test;
10+
using Microsoft.Extensions.FileProviders;
911
using Xunit;
1012

1113
namespace Microsoft.Extensions.Configuration
@@ -219,5 +221,64 @@ public void ThrowFormatExceptionWhenFileIsEmpty()
219221
var exception = Assert.Throws<FormatException>(() => LoadProvider(@""));
220222
Assert.Contains("Could not parse the JSON file.", exception.Message);
221223
}
224+
225+
[Theory]
226+
[InlineData(true)]
227+
[InlineData(false)]
228+
public void AddJsonFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User(bool disposeConfigRoot)
229+
{
230+
string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddJsonFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User)}.json");
231+
File.WriteAllText(filePath, @"{ ""some"": ""value"" }");
232+
233+
IConfigurationRoot config = new ConfigurationBuilder().AddJsonFile(filePath, optional: false).Build();
234+
JsonConfigurationProvider jsonConfigurationProvider = config.Providers.OfType<JsonConfigurationProvider>().Single();
235+
236+
Assert.NotNull(jsonConfigurationProvider.Source.FileProvider);
237+
PhysicalFileProvider fileProvider = (PhysicalFileProvider)jsonConfigurationProvider.Source.FileProvider;
238+
Assert.False(GetIsDisposed(fileProvider));
239+
240+
if (disposeConfigRoot)
241+
{
242+
(config as IDisposable).Dispose(); // disposing ConfigurationRoot
243+
}
244+
else
245+
{
246+
jsonConfigurationProvider.Dispose(); // disposing JsonConfigurationProvider
247+
}
248+
249+
Assert.True(GetIsDisposed(fileProvider));
250+
}
251+
252+
[Fact]
253+
public void AddJsonFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User()
254+
{
255+
string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddJsonFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User)}.json");
256+
File.WriteAllText(filePath, @"{ ""some"": ""value"" }");
257+
258+
PhysicalFileProvider fileProvider = new(Path.GetDirectoryName(filePath));
259+
JsonConfigurationProvider configurationProvider = new(new JsonConfigurationSource()
260+
{
261+
Path = filePath,
262+
FileProvider = fileProvider
263+
});
264+
IConfigurationRoot config = new ConfigurationBuilder().AddJsonFile(configurationProvider.Source.FileProvider, filePath, optional: true, reloadOnChange: false).Build();
265+
266+
Assert.False(GetIsDisposed(fileProvider));
267+
268+
(config as IDisposable).Dispose(); // disposing ConfigurationRoot that does not own the provider
269+
Assert.False(GetIsDisposed(fileProvider));
270+
271+
configurationProvider.Dispose(); // disposing JsonConfigurationProvider that does not own the provider
272+
Assert.False(GetIsDisposed(fileProvider));
273+
274+
fileProvider.Dispose(); // disposing PhysicalFileProvider itself
275+
Assert.True(GetIsDisposed(fileProvider));
276+
}
277+
278+
private static bool GetIsDisposed(PhysicalFileProvider fileProvider)
279+
{
280+
System.Reflection.FieldInfo isDisposedField = typeof(PhysicalFileProvider).GetField("_disposed", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
281+
return (bool)isDisposedField.GetValue(fileProvider);
282+
}
222283
}
223284
}

src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33

44
using System;
55
using System.IO;
6+
using System.Linq;
67
using System.Security.Cryptography;
78
using System.Security.Cryptography.Xml;
89
using System.Tests;
910
using System.Xml;
1011
using Microsoft.Extensions.Configuration.Test;
12+
using Microsoft.Extensions.FileProviders;
1113
using Xunit;
1214

1315
namespace Microsoft.Extensions.Configuration.Xml.Test
@@ -779,5 +781,64 @@ public void LoadKeyValuePairsFromValidEncryptedXml()
779781
Assert.Equal("AnotherTestConnectionString", xmlConfigSrc.Get("data.setting:inventory:connectionstring"));
780782
Assert.Equal("MySql", xmlConfigSrc.Get("Data.setting:Inventory:Provider"));
781783
}
784+
785+
[Theory]
786+
[InlineData(true)]
787+
[InlineData(false)]
788+
public void AddXmlFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User(bool disposeConfigRoot)
789+
{
790+
string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddXmlFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User)}.xml");
791+
File.WriteAllText(filePath, @"<settings><My><Nice>Settings</Nice></My></settings>");
792+
793+
IConfigurationRoot config = new ConfigurationBuilder().AddXmlFile(filePath, optional: false).Build();
794+
XmlConfigurationProvider xmlConfigurationProvider = config.Providers.OfType<XmlConfigurationProvider>().Single();
795+
796+
Assert.NotNull(xmlConfigurationProvider.Source.FileProvider);
797+
PhysicalFileProvider fileProvider = (PhysicalFileProvider)xmlConfigurationProvider.Source.FileProvider;
798+
Assert.False(GetIsDisposed(fileProvider));
799+
800+
if (disposeConfigRoot)
801+
{
802+
(config as IDisposable).Dispose(); // disposing ConfigurationRoot
803+
}
804+
else
805+
{
806+
xmlConfigurationProvider.Dispose(); // disposing XmlConfigurationProvider
807+
}
808+
809+
Assert.True(GetIsDisposed(fileProvider));
810+
}
811+
812+
[Fact]
813+
public void AddXmlFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User()
814+
{
815+
string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddXmlFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User)}.xml");
816+
File.WriteAllText(filePath, @"<settings><My><Nice>Settings</Nice></My></settings>");
817+
818+
PhysicalFileProvider fileProvider = new(Path.GetDirectoryName(filePath));
819+
XmlConfigurationProvider configurationProvider = new(new XmlConfigurationSource()
820+
{
821+
Path = filePath,
822+
FileProvider = fileProvider
823+
});
824+
IConfigurationRoot config = new ConfigurationBuilder().AddXmlFile(configurationProvider.Source.FileProvider, filePath, optional: true, reloadOnChange: false).Build();
825+
826+
Assert.False(GetIsDisposed(fileProvider));
827+
828+
(config as IDisposable).Dispose(); // disposing ConfigurationRoot that does not own the provider
829+
Assert.False(GetIsDisposed(fileProvider));
830+
831+
configurationProvider.Dispose(); // disposing XmlConfigurationProvider
832+
Assert.False(GetIsDisposed(fileProvider));
833+
834+
fileProvider.Dispose(); // disposing PhysicalFileProvider itself
835+
Assert.True(GetIsDisposed(fileProvider));
836+
}
837+
838+
private static bool GetIsDisposed(PhysicalFileProvider fileProvider)
839+
{
840+
System.Reflection.FieldInfo isDisposedField = typeof(PhysicalFileProvider).GetField("_disposed", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
841+
return (bool)isDisposedField.GetValue(fileProvider);
842+
}
782843
}
783844
}

src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ protected void SetPropertyValue(System.Configuration.ConfigurationProperty prop,
207207
protected virtual void SetReadOnly() { }
208208
protected virtual void Unmerge(System.Configuration.ConfigurationElement sourceElement, System.Configuration.ConfigurationElement parentElement, System.Configuration.ConfigurationSaveMode saveMode) { }
209209
}
210-
[System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
211210
public abstract partial class ConfigurationElementCollection : System.Configuration.ConfigurationElement, System.Collections.ICollection, System.Collections.IEnumerable
212211
{
213212
protected ConfigurationElementCollection() { }

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/Resources/xlf/Strings.cs.xlf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
<body>
55
<trans-unit id="AnalysisFailedDescription">
66
<source>The analysis required to generate code for this interface or method has failed due to an unexpected code pattern. If you are using new or unconventional syntax, consider using other syntax.</source>
7-
<target state="new">The analysis required to generate code for this interface or method has failed due to an unexpected code pattern. If you are using new or unconventional syntax, consider using other syntax.</target>
7+
<target state="translated">Analýza požadovaná ke generování kódu pro toto rozhraní nebo metodu se nezdařila kvůli neočekávanému vzoru kódu. Pokud používáte novou nebo nekonvenční syntaxi, zvažte použití jiné syntaxe.</target>
88
<note />
99
</trans-unit>
1010
<trans-unit id="AnalysisFailedInterfaceMessage">
1111
<source>Analysis of interface '{0}' has failed. ComInterfaceGenerator will not generate code for this interface.</source>
12-
<target state="new">Analysis of interface '{0}' has failed. ComInterfaceGenerator will not generate code for this interface.</target>
12+
<target state="translated">Analýza rozhraní {0} se nezdařila. ComInterfaceGenerator nevygeneruje kód pro toto rozhraní.</target>
1313
<note />
1414
</trans-unit>
1515
<trans-unit id="AnalysisFailedMethodMessage">
1616
<source>Analysis of method '{0}' has failed. ComInterfaceGenerator will not generate code for this method.</source>
17-
<target state="new">Analysis of method '{0}' has failed. ComInterfaceGenerator will not generate code for this method.</target>
17+
<target state="translated">Analýza metody {0} se nezdařila. ComInterfaceGenerator nevygeneruje kód pro tuto metodu.</target>
1818
<note />
1919
</trans-unit>
2020
<trans-unit id="AnalysisFailedTitle">
2121
<source>Analysis for generation has failed.</source>
22-
<target state="new">Analysis for generation has failed.</target>
22+
<target state="translated">Analýza pro generování se nezdařila</target>
2323
<note />
2424
</trans-unit>
2525
<trans-unit id="ConfigurationNotSupportedDescription">

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/Resources/xlf/Strings.de.xlf

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
<body>
55
<trans-unit id="AnalysisFailedDescription">
66
<source>The analysis required to generate code for this interface or method has failed due to an unexpected code pattern. If you are using new or unconventional syntax, consider using other syntax.</source>
7-
<target state="new">The analysis required to generate code for this interface or method has failed due to an unexpected code pattern. If you are using new or unconventional syntax, consider using other syntax.</target>
7+
<target state="translated">Die Analyse, die erforderlich ist, um Code für diese Schnittstelle oder Methode zu erzeugen, ist aufgrund eines unerwarteten Codemusters fehlgeschlagen. Wenn Sie eine neue oder unkonventionelle Syntax verwenden, sollten Sie eine andere Syntax verwenden.</target>
88
<note />
99
</trans-unit>
1010
<trans-unit id="AnalysisFailedInterfaceMessage">
1111
<source>Analysis of interface '{0}' has failed. ComInterfaceGenerator will not generate code for this interface.</source>
12-
<target state="new">Analysis of interface '{0}' has failed. ComInterfaceGenerator will not generate code for this interface.</target>
12+
<target state="translated">Fehler bei der Analyse der Schnittstelle "{0}". ComInterfaceGenerator generiert keinen Code für diese Methode.</target>
1313
<note />
1414
</trans-unit>
1515
<trans-unit id="AnalysisFailedMethodMessage">
1616
<source>Analysis of method '{0}' has failed. ComInterfaceGenerator will not generate code for this method.</source>
17-
<target state="new">Analysis of method '{0}' has failed. ComInterfaceGenerator will not generate code for this method.</target>
17+
<target state="translated">Fehler bei der Analyse der Methode "{0}". ComInterfaceGenerator generiert keinen Code für diese Methode.</target>
1818
<note />
1919
</trans-unit>
2020
<trans-unit id="AnalysisFailedTitle">
2121
<source>Analysis for generation has failed.</source>
22-
<target state="new">Analysis for generation has failed.</target>
22+
<target state="translated">Fehler bei der Analyse für die Generierung.</target>
2323
<note />
2424
</trans-unit>
2525
<trans-unit id="ConfigurationNotSupportedDescription">
@@ -114,12 +114,12 @@
114114
</trans-unit>
115115
<trans-unit id="InvalidGeneratedComInterfaceAttributeUsageDescription">
116116
<source>Interfaces attributed with 'GeneratedComInterfaceAttribute' must be partial, non-generic, and must specify a GUID with 'System.Runtime.InteropServices.GuidAttribute'.</source>
117-
<target state="new">Interfaces attributed with 'GeneratedComInterfaceAttribute' must be partial, non-generic, and must specify a GUID with 'System.Runtime.InteropServices.GuidAttribute'.</target>
117+
<target state="translated">Schnittstellen, die mit "GeneratedComInterfaceAttribute" attributiert sind, müssen partielle, nicht generische Schnittstellen sein und eine GUID mit "System.Runtime.InteropServices.GuidAttribute" angeben.</target>
118118
<note />
119119
</trans-unit>
120120
<trans-unit id="InvalidGeneratedComInterfaceAttributeUsageInterfaceIsGeneric">
121121
<source>Interface '{0}' is attributed with 'GeneratedComInterfaceAttribute' but is generic.</source>
122-
<target state="new">Interface '{0}' is attributed with 'GeneratedComInterfaceAttribute' but is generic.</target>
122+
<target state="translated">Die Schnittstelle "{0}" wird mit "GeneratedComInterfaceAttribute" attributiert, ist aber generisch.</target>
123123
<note />
124124
</trans-unit>
125125
<trans-unit id="InvalidGeneratedComInterfaceAttributeUsageMissingGuidAttribute">

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/Resources/xlf/Strings.fr.xlf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
<body>
55
<trans-unit id="AnalysisFailedDescription">
66
<source>The analysis required to generate code for this interface or method has failed due to an unexpected code pattern. If you are using new or unconventional syntax, consider using other syntax.</source>
7-
<target state="new">The analysis required to generate code for this interface or method has failed due to an unexpected code pattern. If you are using new or unconventional syntax, consider using other syntax.</target>
7+
<target state="translated">L’analyse requise pour générer du code pour cette interface ou cette méthode a échoué en raison d’un modèle de code inattendu. Si vous utilisez une syntaxe nouvelle ou syntaxe correcte, utilisez une autre syntaxe.</target>
88
<note />
99
</trans-unit>
1010
<trans-unit id="AnalysisFailedInterfaceMessage">
1111
<source>Analysis of interface '{0}' has failed. ComInterfaceGenerator will not generate code for this interface.</source>
12-
<target state="new">Analysis of interface '{0}' has failed. ComInterfaceGenerator will not generate code for this interface.</target>
12+
<target state="translated">Nous n’avons pas pu analyser l’interface '{0}'. ComInterfaceGenerator ne générera pas de code pour cette interface.</target>
1313
<note />
1414
</trans-unit>
1515
<trans-unit id="AnalysisFailedMethodMessage">
1616
<source>Analysis of method '{0}' has failed. ComInterfaceGenerator will not generate code for this method.</source>
17-
<target state="new">Analysis of method '{0}' has failed. ComInterfaceGenerator will not generate code for this method.</target>
17+
<target state="translated">Nous n’avons pas pu analyser la méthode '{0}'. ComInterfaceGenerator ne générera pas de code pour cette méthode.</target>
1818
<note />
1919
</trans-unit>
2020
<trans-unit id="AnalysisFailedTitle">
2121
<source>Analysis for generation has failed.</source>
22-
<target state="new">Analysis for generation has failed.</target>
22+
<target state="translated">Échec de l’analyse de la génération.</target>
2323
<note />
2424
</trans-unit>
2525
<trans-unit id="ConfigurationNotSupportedDescription">

0 commit comments

Comments
 (0)