Skip to content

Ensure serializer reflection-dependency sentinel is accurate #66522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 15, 2022
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
Expand Up @@ -9,6 +9,7 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Converters;
using System.Text.Json.Serialization.Metadata;
using System.Threading;

namespace System.Text.Json
{
Expand All @@ -29,11 +30,14 @@ public sealed partial class JsonSerializerOptions
[RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)]
private static void RootReflectionSerializerDependencies()
{
if (s_defaultSimpleConverters is null)
// s_typeInfoCreationFunc is the last field assigned.
// Use it as the sentinel to ensure that all dependencies are initialized.
if (Volatile.Read(ref s_typeInfoCreationFunc) is null)
{
s_defaultSimpleConverters = GetDefaultSimpleConverters();
s_defaultFactoryConverters = GetDefaultFactoryConverters();
s_typeInfoCreationFunc = CreateJsonTypeInfo;
// Explicitly ensure that the previous fields are initialized along with this one.
Volatile.Write(ref s_typeInfoCreationFunc, CreateJsonTypeInfo);
}

[RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Threading;

namespace System.Text.Json
{
Expand Down Expand Up @@ -579,7 +580,7 @@ internal MemberAccessor MemberAccessorStrategy
/// <summary>
/// Whether the options instance has been primed for reflection-based serialization.
/// </summary>
internal bool IsInitializedForReflectionSerializer { get; private set; }
internal bool IsInitializedForReflectionSerializer;

/// <summary>
/// Initializes the converters for the reflection-based serializer.
Expand All @@ -589,7 +590,7 @@ internal MemberAccessor MemberAccessorStrategy
internal void InitializeForReflectionSerializer()
{
RootReflectionSerializerDependencies();
IsInitializedForReflectionSerializer = true;
Volatile.Write(ref IsInitializedForReflectionSerializer, true);
if (_cachingContext != null)
{
_cachingContext.Options.IsInitializedForReflectionSerializer = true;
Expand All @@ -610,7 +611,9 @@ private JsonTypeInfo GetJsonTypeInfoFromContextOrCreate(Type type)
return null!;
}

Debug.Assert(s_typeInfoCreationFunc != null);
Debug.Assert(
s_typeInfoCreationFunc != null,
"Reflection-based JsonTypeInfo creator should be initialized if IsInitializedForReflectionSerializer is true.");
return s_typeInfoCreationFunc(type, this);
}

Expand Down