-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Add the CurrentUserOnly
and CurrentSessionOnly
options for named Mutex
, Semaphore
, and EventWaitHandle
#112213
base: main
Are you sure you want to change the base?
Conversation
Note regarding the
|
1 similar comment
Note regarding the
|
Tagging subscribers to this area: @mangod9 |
#define SHARED_MEMORY_UNIQUE_TEMP_NAME_TEMPLATE ".coreclr.XXXXXX" | ||
|
||
#define SHARED_MEMORY_MAX_SESSION_ID_CHAR_COUNT (10) | ||
#define SHARED_MEMORY_UNIQUE_TEMP_NAME_TEMPLATE ".dotnet.XXXXXX" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that .NET 10+ apps will no longer be able to sync with apps running using older .NET version. It seems we will need to document this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only used as the pattern for mkdtemp()
when creating the .dotnet
, .dotnet-uidN
, and shm
directories, where a directory with a unique name is created first and renamed to one of those. It shouldn't affect compatibility, the user-unscoped shared memory files and lock files are still stored under /tmp/.dotnet/
.
/// </summary> | ||
public struct NamedWaitHandleOptions | ||
{ | ||
private bool _notCurrentUserOnly; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder what is the benefit of storing these as negative (_notXXX).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We wanted a zero-initialized struct as in default(NamedWaitHandleOptions)
to have CurrentUserOnly == true
and CurrentSessionOnly == true
, so the fields store the NOT of the property values.
|
||
if (myHandle.IsInvalid) | ||
{ | ||
myHandle.Dispose(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reason for disposing the handle when it is invalid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would suppress the finalizer for the safe handle. It's on a path where the safe handle won't be used anymore, so it should ideally be disposed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 23 out of 38 changed files in this pull request and generated no comments.
Files not reviewed (15)
- src/coreclr/pal/inc/pal.h: Language not supported
- src/coreclr/pal/src/include/pal/mutex.hpp: Language not supported
- src/coreclr/pal/src/include/pal/sharedmemory.h: Language not supported
- src/coreclr/pal/src/include/pal/sharedmemory.inl: Language not supported
- src/coreclr/pal/src/init/pal.cpp: Language not supported
- src/coreclr/pal/src/synchobj/mutex.cpp: Language not supported
- src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp: Language not supported
- src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/nopal.cpp: Language not supported
- src/libraries/System.Private.CoreLib/src/Resources/Strings.resx: Language not supported
- src/libraries/Common/src/Interop/Windows/Advapi32/Interop.OpenThreadToken_SafeAccessTokenHandle.cs: Evaluated as low risk
- src/libraries/Common/src/Interop/Windows/Interop.Errors.cs: Evaluated as low risk
- src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Constants.cs: Evaluated as low risk
- src/libraries/Common/src/System/Threading/OpenExistingResult.cs: Evaluated as low risk
- src/libraries/Common/src/Interop/Windows/Advapi32/Interop.GetSecurityInfoByHandle.cs: Evaluated as low risk
- src/libraries/Common/src/Interop/Windows/Advapi32/Interop.OpenThreadToken.cs: Evaluated as low risk
src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs
Outdated
Show resolved
Hide resolved
Do we have people lined up to use these new APIs so that we can verify that they work well in practice? |
PowerShell was a use case for user-scoped mutexes. I'll reach out to them to see if they'd be able to test some previews. The plan was also to deprecate the old APIs with a |
Rebased to update with main |
…`Mutex`, `Semaphore`, and `EventWaitHandle`
…lr implementation
Mutex
,Semaphore
, andEventWaitHandle
, added overloads for methods with aname
argument to also include aNamedWaitHandleOptions options
argument. TheCurrentUserOnly
option indicates whether the object should be limited in access to the current user. TheCurrentSessionOnly
option indicates whether the object object is intended to be used only within the current session (an alternative to the name prefixes, such asGlobal\
). The default value forNamedWaitHandleOptions
hasCurrentUserOnly=true
andCurrentSessionOnly=true
.CurrentUserOnly=true
. Sharing the CoreCLR Unix named mutex implementation with NativeAOT/Mono is left to a separate change. Most of what is described below whenCurrentUserOnly=true
on Unixes refers to the CoreCLR implementation.name
argument but without anoptions
argument in a separate changeWindows with
CurrentUserOnly=true
When creating a named mutex, a security descriptor is created and assigned to the object.
BUILTIN\Administrators
group theREAD_CONTROL
access right to enable reading the security info for diagnostic purposesWaitHandleCannotBeOpenedException
is thrownUnixes with
CurrentUserOnly=true
/tmp/.dotnet-uidN/
whereN
is the effective user ID/tmp/
(or equivalent) was chosen mainly for the automatic cleanup, as the number of files can add up in cases where mutexes are not disposed, particularly when randomly generated names are used upon each invocation of a process. Due to the use of a global location/tmp/
or equivalent, it would be possible for a user to deny access to the.dotnet-uidN
directory of a different user if the directory hadn't been created yet. An alternative considered was to use the home directory and introduce some kind of periodic cleanup strategy, but there are also other tradeoffs./tmp/
or equivalent must either have the sticky bit, or it must be owned by the current user and without write access for any other user. Otherwise, an exception is thrown./tmp/.dotnet-uidN/
directory and files/directories under it are limited in access to the current userNamespaces
CurrentSessionOnly=true
is close, but it is possible for multiple users to be running code simultaneously in the same session. There is a global namespace, and a namespace per session. WhenCurrentUserOnly=true
, callers may need to ensure that the name used is distinguished for different users.CurrentUserOnly=true
, so each user has a separate namespace for objects, including for session-scoped and session-unscoped objects.