Merge pull request #36268 from kouvel/NamedMutexFix
authorKoundinya Veluri <kouvel@users.noreply.github.com>
Wed, 13 May 2020 16:37:16 +0000 (12:37 -0400)
committerGitHub <noreply@github.com>
Wed, 13 May 2020 16:37:16 +0000 (12:37 -0400)
commitf3a3e647f3c19897f1c74922535ba5e8b06700d5
tree11ba167d38ccfc4d387be2cb3c3732d166199747
parent5615bdaea8ee754f97f53741b00a3c02aa84111b
parentc67b1086173517bd2b64a557041048a9a6faefa6
Merge pull request #36268 from kouvel/NamedMutexFix

Fix Unix named mutex crash during some race conditions

Below when I refer to "mutex" I'm referring to the underlying mutex object, not an instance of the `Mutex` class.
- When the last reference to a mutex is closed while the lock is held by some thread and a pthread mutex is used, the mutex was attempted to be destroyed but that has undefined behavior
- There doesn't seem to be a way to behave exactly like on Windows for this corner case, where the mutex is destroyed when the last reference to it is released, regardless of which process has the mutex locked and which process releases the last reference to it (they could be two different processes), including in cases of abrupt shutdown
- For this corner case I settled on what seems like a decent solution and compatible with older runtimes:
  - When a process releases its last reference to the mutex
    - If that mutex is locked by the same thread, the lock is abandoned and the process no longer references the mutex
    - If that mutex is locked by a different thread, the lifetime of the mutex is extended with an implicit ref. The implicit ref prevents this or other processes from attempting to destroy the mutex while it is locked. The implicit ref is removed in either of these cases:
      - The mutex gets another reference from within the same process
      - The thread that owns the lock exits and abandons the mutex, at which point that would be the last reference to the mutex and the process would not reference the mutex anymore
  - The implementation based on file locks is less restricted, but for consistency that implementation also follows the same behavior
- There was also a race between an exiting thread abandoning one of its locked named mutexes and another thread releasing the last reference to it, fixed by using the creation/deletion process lock to synchronize

Fix for https://github.com/dotnet/runtime/issues/34271 in master
Closes https://github.com/dotnet/runtime/issues/28449 - probably doesn't fix the issue, but trying to enable it to see if it continues to fail