Skip to content

Handle transient shared-memory directory state during named mutex open/create#130061

Draft
Copilot wants to merge 6 commits into
mainfrom
copilot/fix-crossprocess-namedmutex-test
Draft

Handle transient shared-memory directory state during named mutex open/create#130061
Copilot wants to merge 6 commits into
mainfrom
copilot/fix-crossprocess-namedmutex-test

Conversation

Copilot AI commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

MutexTests.CrossProcess_NamedMutex_ConcurrentCreateOrOpen was failing in CI on Unix when one process observed /tmp/.dotnet*/shm between directory creation and final ownership/permission normalization. This change makes named mutex shared-memory directory validation tolerate that transient state instead of failing the open/create path.

  • Directory race handling

    • Extend SharedMemoryHelpers.EnsureDirectoryExists with the same short transient retry model already used for shared-memory files.
    • Retry when stat/validation sees a directory before the creating process has finished applying the expected owner or mode.
  • Failure modes addressed

    • User-scoped directories temporarily reported as owned by the wrong UID.
    • Non-user-scoped directories temporarily reported without the expected owner permissions.
  • Scope

    • No behavioral change to the steady state validation rules.
    • The change only relaxes the transient handoff window during concurrent cross-process creation/open.
if (error.Error == Interop.Error.ENOENT && RetryOnTransientPermissionFailure())
{
    continue;
}

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 1, 2026 01:50
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 1, 2026 01:57
Copilot AI changed the title [WIP] Fix failing CrossProcess_NamedMutex_ConcurrentCreateOrOpen test in CI Handle transient shared-memory directory state during named mutex open/create Jul 1, 2026
Copilot AI requested a review from jkotas July 1, 2026 01:58
Copilot finished work on behalf of jkotas July 1, 2026 01:58
{
throw new IOException(SR.Format(SR.IO_SharedMemory_DirectoryNotOwnedByUid, directoryPath, id.Uid));
}
if (!createIfNotExist || transientRetryCount >= TransientRetryCount)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Are you sure createIfNotExist condition is right here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right; that condition was too strict for the open path. EnsureDirectoryExists(..., createIfNotExist: false) still returns false immediately when the directory is actually missing, but it also needs to tolerate the transient owner/mode window when another process has already created the directory and is finishing normalization. I removed the createIfNotExist gate in 18f567c so only that transient validation case retries; real failures still throw after the bounded retry window.

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 1, 2026 02:57
Copilot finished work on behalf of jkotas July 1, 2026 03:03
Copilot AI requested a review from jkotas July 1, 2026 03:03

unsafe
// If the path exists, check that it's a directory
if (statResult != 0 || (fileStatus.Mode & Interop.Sys.FileTypes.S_IFDIR) == 0)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Simplify the code flow here, like:

if (statResult != 0)
{
...
}

// If the path exists, check that it's a directory
if ((fileStatus.Mode & Interop.Sys.FileTypes.S_IFDIR) == 0)
{
    throw new IOException(SR.Format(SR.IO_SharedMemory_PathExistsButNotDirectory, directoryPath));
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 0486326. The statResult != 0 path is now handled separately from the non-directory check.

return true;
}

if (!RetryOnTransientPermissionFailure())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Change the logic to be possitive everywhere

if (RetryOnTransientPermissionFailure())
{
    continue;
}

throw new ....

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 2e680d1. I flipped the remaining retry sites in EnsureDirectoryExists to the positive if (RetryOnTransientPermissionFailure()) { continue; } flow for consistency.

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 1, 2026 06:20
Copilot finished work on behalf of jkotas July 1, 2026 06:21
Copilot AI requested a review from jkotas July 1, 2026 06:21
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

System.Threading.Tests.MutexTests.CrossProcess_NamedMutex_ConcurrentCreateOrOpen failing in CI

2 participants