-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Named mutex not supported on Unix #5211
Comments
Related to #4370 |
Duplicate of issue #4370. |
I wouldn't say it's a duplicate. That issue was resolved by removing the functionality. It would be nice to actually fix the actual problem and restore the functionality. |
Miguel can correct me if I'm wrong, but I don't believe Mono implements this either, or more specifically I believe they implement it the same general manner that the coreclr did before it was disabled to throw those exceptions: the names are only process-wide, not cross-process. That's why we decided to throw exceptions on coreclr; otherwise, since names are typically used for cross-process synchronization, you use the names thinking you're getting cross-process synchronization, but in reality you've just got a bunch of race conditions silently waiting to cause problems. |
Reopened because of @mikedn comment. |
My search for ways to add a cross-process mutex didn't yield many options. I'm currently planning on this:
Currently, we are looking for the following features:
Any other ideas? CC @kangaroo |
cc @krytarowski for NetBSD |
I don't have anything portable offhand, other than maybe |
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Related to dotnet/coreclr#5030 Related to dotnet/coreclr#3422
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
The tests removed would fail soon after dotnet/coreclr#5030 is merged. Related to dotnet/coreclr#5030 Related to dotnet#8625 Related to dotnet/coreclr#3422
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Fixes #3422 - On systems that support pthread process-shared robust recursive mutexes, they will be used - On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits. Shared memory files: - Session-scoped mutexes (name not prefixed, or prefixed with Local\) go in /tmp/coreclr/shm/session<sessionId>/<mutexName> - Globally-scoped mutexes (name prefixed with Global\) go in /tmp/coreclr/shm/global/<mutexName> - Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data stored - Creation and deletion is synchronized using an exclusive file lock on the shm directory - Any process using the shared memory file holds a shared file lock on the shared memory file - Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is valid. If no other processes have the mutex open, the file is reinitialized. - Upon releasing the last reference to a mutex in a process, it will try to get an exclusive lock on the shared memory file to see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty. The coreclr and shm directories are not deleted. - This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about that. Lock files when using file locks: - In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the shared memory file is used for lifetime purposes. - These files go in /tmp/coreclr/lockfiles/session<sessionId>|global/<mutexName> - The file is empty, and is only used for file locks Process data - See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored - Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem to be easily usable in the PAL. I'll look into that and will fix later. - Refers to the associated shared memory, and knows how to clean up both the process data and shared data - When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given file descriptor. Abandon detection - When a lock is acquired, the process data is added to a linked list on the owning thread - When a thread exits, the list is walked, each mutex is flagged as abandoned and released - For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the mutex was abandoned. Miscellaneous - CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header for the mutex name. - Some of the above features are already available in the PAL, but not quite in a way that I can use for this purpose. The existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
Related to dotnet/coreclr#5030 Related to dotnet/coreclr#3422
Related to dotnet/coreclr#5030 Related to dotnet/coreclr#3422
Related to dotnet/coreclr#5030 Related to dotnet/coreclr#3422
Related to dotnet/coreclr#5030 Related to dotnet/coreclr#3422
Mono's implementation is not cross-process. |
I'm confused, what's the current state of named Mutexes in core? Will they work on windows and linux? |
There was an implementation with POSIX robust mutexes on Linux. |
so that's a yes? It'd be really nice if yes as I can get rid of the file locking hacks! |
I guess so, this is why I need to implement POSIX robust mutexes on my platform (NetBSD). |
I've just tried on Ubuntu 14.04 and the answer is a no |
What code did you try? Named mutexes should work fine on in Ubuntu. |
Interesting, this is my code, other processes are not honouring the mutex and are acquiring the mutex and repeating the same work. It works in Windows as expected.
|
What name did you use? By default, names have session scope and sessions are more granular on Unix (each terminal gets its own session). If you haven't already, please try adding a "Global" prefix to the name minus the quotes. There is build-time code to detect if the system supports POSIX robust mutexes, see https://github.com/dotnet/coreclr/blob/master/src/pal/src/configure.cmake#L997 and https://github.com/dotnet/coreclr/blob/master/src/pal/src/configure.cmake#L1020. Based on that, it would use POSIX robust mutexes or file locks, but it should work either way. |
Although unrelated, in the above code, when an AbandonedMutexException is thrown, the thread is still given ownership of the lock, so you'd have to ReleaseMutex on that path as well |
I prefixed the name with "Global\"as suggested here to no avail. I am running the processes in multiple screen instances. This is with RC4 (installed with apt-get) |
Would it be possible to provide a small runnable repro? I can give it a try and see what's going on. |
I took this down to the most basic example I could make and it worked... so I worked backwards and fixed. It was the missing "Global\" along with a few other things - User error - thanks and sorry! |
Ok great |
Hi! I have try the following program in Debian 9 and it seems mutex is not global (cross-process):
I started two instances of the application and both of them counting down simultaneously. Would you be so kind to clarify is it my mistake or Mono bug? |
Are you using .NET Core or Mono? |
@stephentoub, I try Mono |
Thanks. This issue / repo are for coreclr. Can you open an issue instead in http://github.com/mono/mono? |
@stephentoub, Oh, I see. I chose wrong project. My apologies! |
No worries; it's confusing :) |
Sorry for pinging on old thread. What is the situation for |
Correct. |
@stephentoub is there documentation about how global mutex works on each platform supported by net core? |
Documentation about the implementation? I don't know if @kouvel published a design doc anywhere for the Unix implementations; he might be able to point you to something. Your best bet though is probably just the implementation source code. |
Any way you can point me to it? The code base is extensive and so far I've had no luck with it. |
The closest summary is probably from the original PR: dotnet/coreclr#5030. I thought they were in the code somewhere but apparently not, I have filed an issue to get those into code. Most of the relevant code is here:
Roughly, they should behave the same way as on Windows. There may be some corner cases where they behave slightly differently, for example when the last handle to a mutex object is closed while the lock is held by a different thread. |
On Windows the native objects are used (CreateMutex, etc.), on Linuxes where pthread robust mutexes are supported, they are used, and on OSX file locks are used. |
Creating a named mutex on Unix currently throws a PlatformNotSupportedException stating "Named synchronization primitives are not supported on this platform".
Is this scheduled to arrive ? I'm sure @migueldeicaza will be eager to port this from Mono to .NET Core :p
Personally, I don't think it makes sense to expose APIs on both Windows and Unix, but only implement them on one of them. In what way does the Portability Analyzer even take this into account ?
The text was updated successfully, but these errors were encountered: