Skip to content

Commit 25446d0

Browse files
committed
Remove named mutex support from the CoreCLR PAL
1 parent b22da40 commit 25446d0

File tree

22 files changed

+72
-6507
lines changed

22 files changed

+72
-6507
lines changed

src/coreclr/pal/inc/pal.h

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -759,42 +759,11 @@ CreateMutexExW(
759759
IN DWORD dwFlags,
760760
IN DWORD dwDesiredAccess);
761761

762-
PALIMPORT
763-
HANDLE
764-
PALAPI
765-
PAL_CreateMutexW(
766-
IN BOOL bInitialOwner,
767-
IN LPCWSTR lpName,
768-
IN BOOL bCurrentUserOnly,
769-
IN LPSTR lpSystemCallErrors,
770-
IN DWORD dwSystemCallErrorsBufferSize);
771-
772762
// CreateMutexExW: dwFlags
773763
#define CREATE_MUTEX_INITIAL_OWNER ((DWORD)0x1)
774764

775765
#define CreateMutex CreateMutexW
776766

777-
PALIMPORT
778-
HANDLE
779-
PALAPI
780-
OpenMutexW(
781-
IN DWORD dwDesiredAccess,
782-
IN BOOL bInheritHandle,
783-
IN LPCWSTR lpName);
784-
785-
PALIMPORT
786-
HANDLE
787-
PALAPI
788-
PAL_OpenMutexW(
789-
IN LPCWSTR lpName,
790-
IN BOOL bCurrentUserOnly,
791-
IN LPSTR lpSystemCallErrors,
792-
IN DWORD dwSystemCallErrorsBufferSize);
793-
794-
#ifdef UNICODE
795-
#define OpenMutex OpenMutexW
796-
#endif
797-
798767
PALIMPORT
799768
BOOL
800769
PALAPI

src/coreclr/pal/src/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ set(SOURCES
200200
safecrt/wcsncat_s.cpp
201201
safecrt/wcsncpy_s.cpp
202202
safecrt/wmakepath_s.cpp
203-
sharedmemory/sharedmemory.cpp
204203
synchobj/event.cpp
205204
synchobj/semaphore.cpp
206205
synchobj/mutex.cpp

src/coreclr/pal/src/include/pal/context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern "C"
2929
#include <pthread.h>
3030

3131
#include <minipal/cpuid.h>
32+
#include <static_assert.h>
3233

3334
/* A type to wrap the native context type, which is ucontext_t on some
3435
* platforms and another type elsewhere. */

src/coreclr/pal/src/include/pal/corunix.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ namespace CorUnix
160160
otiAutoResetEvent = 0,
161161
otiManualResetEvent,
162162
otiMutex,
163-
otiNamedMutex,
164163
otiSemaphore,
165164
otiFile,
166165
otiFileMapping,

src/coreclr/pal/src/include/pal/mutex.hpp

Lines changed: 0 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,18 @@ Module Name:
2121
#define _PAL_MUTEX_H_
2222

2323
#include "corunix.hpp"
24-
#include "sharedmemory.h"
2524

2625
#include <pthread.h>
2726

2827
namespace CorUnix
2928
{
3029
extern CObjectType otMutex;
31-
extern CObjectType otNamedMutex;
3230

3331
PAL_ERROR
3432
InternalCreateMutex(
35-
SharedMemorySystemCallErrors *errors,
3633
CPalThread *pThread,
3734
LPSECURITY_ATTRIBUTES lpMutexAttributes,
3835
BOOL bInitialOwner,
39-
LPCSTR lpName,
40-
BOOL bCurrentUserOnly,
4136
HANDLE *phMutex
4237
);
4338

@@ -46,16 +41,6 @@ namespace CorUnix
4641
CPalThread *pThread,
4742
HANDLE hMutex
4843
);
49-
50-
PAL_ERROR
51-
InternalOpenMutex(
52-
SharedMemorySystemCallErrors *errors,
53-
CPalThread *pThread,
54-
LPCSTR lpName,
55-
BOOL bCurrentUserOnly,
56-
HANDLE *phMutex
57-
);
58-
5944
}
6045

6146
#define SYNCSPINLOCK_F_ASYMMETRIC 1
@@ -66,197 +51,4 @@ namespace CorUnix
6651
void SPINLOCKAcquire (LONG * lock, unsigned int flags);
6752
void SPINLOCKRelease (LONG * lock);
6853
DWORD SPINLOCKTryAcquire (LONG * lock);
69-
70-
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
71-
// Named mutex
72-
73-
/*
74-
Design
75-
76-
- On systems that support pthread process-shared robust recursive mutexes, they will be used
77-
- On other systems, file locks are used. File locks unfortunately don't have a timeout in the blocking wait call, and I didn't
78-
find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits.
79-
80-
Shared memory files
81-
- Session-scoped mutexes (name not prefixed, or prefixed with Local) go in /tmp/.dotnet/shm/session<sessionId>/<mutexName>
82-
- Globally-scoped mutexes (name prefixed with Global) go in /tmp/.dotnet/shm/global/<mutexName>
83-
- Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data
84-
stored
85-
- Creation and deletion is synchronized using an exclusive file lock on the shm directory
86-
- Any process using the shared memory file holds a shared file lock on the shared memory file
87-
- Upon creation, if the shared memory file already exists, an exclusive file lock is attempted on it, to see if the file data is
88-
valid. If no other processes have the mutex open, the file is reinitialized.
89-
- 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
90-
see if any other processes have the mutex opened. If not, the file is deleted, along with the session directory if it's empty.
91-
The .dotnet and shm directories are not deleted.
92-
- This allows managing the lifetime of mutex state based on active processes that have the mutex open. Depending on how the
93-
process terminated, the file may still be left over in the tmp directory, I haven't found anything that can be done about
94-
that.
95-
96-
Lock files when using file locks:
97-
- In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the
98-
shared memory file is used for lifetime purposes.
99-
- These files go in /tmp/.dotnet/lockfiles/session<sessionId>|global/<mutexName>
100-
- The file is empty, and is only used for file locks
101-
102-
Process data
103-
- See SharedMemoryProcessDataHeader and NamedMutexProcessData for data stored
104-
- Per mutex name, there is only one instance of process data that is ref-counted. They are currently stored in a linked list in
105-
SharedMemoryManager. It should use a hash table, but of the many hash table implementations that are already there, none seem
106-
to be easily usable in the PAL. I'll look into that and will fix later.
107-
- Refers to the associated shared memory, and knows how to clean up both the process data and shared data
108-
- When using file locks for synchronization, a process-local mutex is also created for synchronizing threads, since file locks
109-
are owned at the file descriptor level and there is only one open file descriptor in the process per mutex name. The
110-
process-local mutex is locked around the file lock, so that only one thread per process is ever trying to flock on a given
111-
file descriptor.
112-
113-
Abandon detection
114-
- When a lock is acquired, the process data is added to a linked list on the owning thread
115-
- When a thread exits, the list is walked, each mutex is flagged as abandoned and released
116-
- For detecting process abruptly terminating, pthread robust mutexes give us that. When using file locks, the file lock is
117-
automatically released by the system. Upon acquiring a lock, the lock owner info in the shared memory is checked to see if the
118-
mutex was abandoned.
119-
120-
Miscellaneous
121-
- CreateMutex and OpenMutex both create new handles for each mutex opened. Each handle just refers to the process data header
122-
for the mutex name.
123-
- 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
124-
existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
125-
*/
126-
127-
// - On FreeBSD, pthread process-shared robust mutexes cannot be placed in shared memory mapped independently by the processes
128-
// involved. See https://github.com/dotnet/runtime/issues/10519.
129-
// - On OSX, pthread robust mutexes were/are not available at the time of this writing. In case they are made available in the
130-
// future, their use is disabled for compatibility.
131-
#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES && \
132-
HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES && \
133-
!(defined(__FreeBSD__) || defined(TARGET_OSX))
134-
135-
#define NAMED_MUTEX_USE_PTHREAD_MUTEX 1
136-
#else
137-
#define NAMED_MUTEX_USE_PTHREAD_MUTEX 0
138-
#endif
139-
140-
enum class NamedMutexError : DWORD
141-
{
142-
MaximumRecursiveLocksReached = ERROR_NOT_ENOUGH_MEMORY,
143-
ThreadHasNotAcquiredMutex = ERROR_NOT_OWNER,
144-
Unknown = ERROR_NOT_ENOUGH_MEMORY
145-
};
146-
147-
enum class MutexTryAcquireLockResult
148-
{
149-
AcquiredLock,
150-
AcquiredLockButMutexWasAbandoned,
151-
TimedOut
152-
};
153-
154-
#if NAMED_MUTEX_USE_PTHREAD_MUTEX
155-
class MutexHelpers
156-
{
157-
public:
158-
static void InitializeProcessSharedRobustRecursiveMutex(SharedMemorySystemCallErrors *errors, pthread_mutex_t *mutex);
159-
static void DestroyMutex(pthread_mutex_t *mutex);
160-
161-
static MutexTryAcquireLockResult TryAcquireLock(SharedMemorySystemCallErrors *errors, pthread_mutex_t *mutex, DWORD timeoutMilliseconds);
162-
static void ReleaseLock(pthread_mutex_t *mutex);
163-
};
164-
#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
165-
166-
class NamedMutexSharedData
167-
{
168-
private:
169-
#if NAMED_MUTEX_USE_PTHREAD_MUTEX
170-
pthread_mutex_t m_lock;
171-
#else // !NAMED_MUTEX_USE_PTHREAD_MUTEX
172-
UINT32 m_timedWaiterCount;
173-
#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
174-
UINT32 m_lockOwnerProcessId;
175-
UINT64 m_lockOwnerThreadId;
176-
bool m_isAbandoned;
177-
178-
public:
179-
NamedMutexSharedData(SharedMemorySystemCallErrors *errors);
180-
~NamedMutexSharedData();
181-
182-
#if NAMED_MUTEX_USE_PTHREAD_MUTEX
183-
public:
184-
pthread_mutex_t *GetLock();
185-
#else // !NAMED_MUTEX_USE_PTHREAD_MUTEX
186-
public:
187-
bool HasAnyTimedWaiters() const;
188-
void IncTimedWaiterCount();
189-
void DecTimedWaiterCount();
190-
#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
191-
192-
public:
193-
bool IsAbandoned() const;
194-
void SetIsAbandoned(bool isAbandoned);
195-
196-
public:
197-
bool IsLockOwnedByAnyThread() const;
198-
bool IsLockOwnedByCurrentThread() const;
199-
void SetLockOwnerToCurrentThread();
200-
void ClearLockOwner();
201-
};
202-
203-
class NamedMutexProcessData : public SharedMemoryProcessDataBase
204-
{
205-
private:
206-
static const UINT8 SyncSystemVersion;
207-
static const DWORD PollLoopMaximumSleepMilliseconds;
208-
209-
private:
210-
SharedMemoryProcessDataHeader *m_processDataHeader;
211-
SIZE_T m_lockCount;
212-
#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
213-
HANDLE m_processLockHandle;
214-
int m_sharedLockFileDescriptor;
215-
#endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
216-
CorUnix::CPalThread *m_lockOwnerThread;
217-
NamedMutexProcessData *m_nextInThreadOwnedNamedMutexList;
218-
bool m_hasRefFromLockOwnerThread;
219-
220-
public:
221-
static SharedMemoryProcessDataHeader *CreateOrOpen(SharedMemorySystemCallErrors *errors, LPCSTR name, bool isUserScope, bool acquireLockIfCreated, bool *createdRef);
222-
static SharedMemoryProcessDataHeader *Open(SharedMemorySystemCallErrors *errors, LPCSTR name, bool isUserScope);
223-
private:
224-
static SharedMemoryProcessDataHeader *CreateOrOpen(SharedMemorySystemCallErrors *errors, LPCSTR name, bool isUserScope, bool createIfNotExist, bool acquireLockIfCreated, bool *createdRef);
225-
226-
public:
227-
NamedMutexProcessData(
228-
SharedMemoryProcessDataHeader *processDataHeader
229-
#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
230-
,
231-
int sharedLockFileDescriptor
232-
#endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
233-
);
234-
235-
public:
236-
virtual bool CanClose() const override;
237-
virtual bool HasImplicitRef() const override;
238-
virtual void SetHasImplicitRef(bool value) override;
239-
virtual void Close(bool isAbruptShutdown, bool releaseSharedData) override;
240-
241-
public:
242-
bool IsLockOwnedByCurrentThread() const
243-
{
244-
return GetSharedData()->IsLockOwnedByCurrentThread();
245-
}
246-
247-
private:
248-
NamedMutexSharedData *GetSharedData() const;
249-
void SetLockOwnerThread(CorUnix::CPalThread *lockOwnerThread);
250-
public:
251-
NamedMutexProcessData *GetNextInThreadOwnedNamedMutexList() const;
252-
void SetNextInThreadOwnedNamedMutexList(NamedMutexProcessData *next);
253-
254-
public:
255-
MutexTryAcquireLockResult TryAcquireLock(SharedMemorySystemCallErrors *errors, DWORD timeoutMilliseconds);
256-
void ReleaseLock();
257-
void Abandon();
258-
private:
259-
void ActuallyReleaseLock();
260-
};
261-
26254
#endif //_PAL_MUTEX_H_

0 commit comments

Comments
 (0)