Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Module containers: a root singleton reaching a module service while a module singleton needs a root singleton deadlocks (lock order root/module inverted)

Closed
#6,542 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

A pull request for this has already been merged.

  • #6545 by @rbuergi — merged

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
csharp
Domain
backend

Research direction

Start with Doc/Architecture/ReadingASiloEviction and the lock ordering described here, then inspect ModuleOwnedRootSource, the Current transient forwarder, ModuleServiceProxy.Invoke, ModuleHealthCheckOptionsForwarder, and ModuleFallbackSource. Build a deterministic two-container regression test that forces both first-time singleton builds to overlap; it should fail before the fix and pass after the lock order is made consistent.

Written by the indexing model from the issue text.

Description

bug sev:M

Found while fixing #6432 (PR #6536). Recorded in Doc/Architecture/ReadingASiloEviction under "What is still open, and not this incident".

The shape. Autofac holds a scope's shared-instance lock for the whole build of a shared instance, and that lock covers every shared instance in the scope.

  • Thread A builds a ROOT singleton. It holds the root container's lock. The singleton's construction reaches a module's service, and that service is not built yet, so A waits for the module container's lock. A root singleton reaches a module through any of these paths:
    • ModuleOwnedRootSource, the stand-ins for module-declared types;
    • the Current route's transient forwarder;
    • ModuleServiceProxy.Invoke, for example an IConfigureOptions<T> a module contributed, invoked when a root singleton reads IOptions<T>.Value in its constructor;
    • ModuleHealthCheckOptionsForwarder, invoked from DefaultHealthCheckService's constructor.
  • Thread B builds a MODULE singleton. It holds that module container's lock. The singleton's construction needs a root singleton that is not built yet. ModuleFallbackSource resolves it in the module scope's RootResolutionScope, and a root singleton is shared in the root, so B waits for the root lock.

The two locks are taken in opposite orders, which is the same deadlock as #6432. It was reproduced with real containers in a throwaway test while reading the #6432 dump. No production dump has shown it yet.

What has NOT been established: whether any running instance has hit it. It needs two first-time builds that overlap.

Wanted: fix it so the two locks are always taken in the same order, with a deterministic two-container regression test that forces the overlap: red before the fix, green after.

🤖 Generated with Claude Code

Dominant language
C#
Stars
12
Forks
5
Avg merge
4h 50m
Merged PRs (30d)
949

Getting set up

  • No Dockerfile or Docker Compose file
  • Has a pull request template
  • No contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Systemorph/MeshWeaver

All issues in Systemorph/MeshWeaver

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.