Skip to content

Is the locking in ReflectionComposablePart correct? #103650

Closed
@omajid

Description

@omajid

var value = _importsCache;
if (value == null)
{
lock (_lock)
{
if (value == null)
{
value = new Dictionary<ImportDefinition, ImportingItem>();
_importsCache = value;
}
}
}
return value;

https://github.com/dotnet/runtime/blob/main/docs/design/specs/Memory-model.md describes how Object assignment to a location potentially accessible by other threads is a release with respect to accesses to the instance’s fields/elements and metadata. But this method only uses the local variable value for locking. Any updates to value will not be seen by other threads. It seems like this might be possible:

  1. Thread 1 sees _importsCache == null and value == null and enters the first conditional
  2. Thread 2 sees _importsCache == null and value == null and enters the first conditional too
  3. Thread 1 takes the lock, sees value == null and initializes _importsCache to a new dictionary
  4. Thread 2 takes the lock, see the local variable value is still null, and then re-initializes _importsCache to another value.

Is this correct/possible?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions