2 using Microsoft.Win32.SafeHandles;
15 [__DynamicallyInvokable]
16 [HostProtection(
SecurityAction.LinkDemand, Synchronization =
true, ExternalThreading =
true)]
19 internal class MutexTryCodeHelper
21 private bool m_initiallyOwned;
23 private MutexCleanupInfo m_cleanupInfo;
25 internal bool m_newMutex;
27 private string m_name;
30 private Win32Native.SECURITY_ATTRIBUTES m_secAttrs;
32 private Mutex m_mutex;
36 internal MutexTryCodeHelper(
bool initiallyOwned, MutexCleanupInfo cleanupInfo,
string name, Win32Native.SECURITY_ATTRIBUTES secAttrs,
Mutex mutex)
38 m_initiallyOwned = initiallyOwned;
39 m_cleanupInfo = cleanupInfo;
41 m_secAttrs = secAttrs;
47 internal void MutexTryCode(
object userData)
58 m_cleanupInfo.inCriticalRegion =
true;
70 num = CreateMutexHandle(m_initiallyOwned, m_name, m_secAttrs, out mutexHandle);
72 if (mutexHandle.IsInvalid)
74 mutexHandle.SetHandleAsInvalid();
75 if (m_name !=
null && m_name.Length != 0 && 6 == num)
79 __Error.WinIOError(num, m_name);
81 m_newMutex = (num != 183);
82 m_mutex.SetHandleInternal(mutexHandle);
83 m_mutex.hasThreadAffinity =
true;
87 internal class MutexCleanupInfo
92 internal bool inCriticalRegion;
95 internal MutexCleanupInfo(
SafeWaitHandle mutexHandle,
bool inCriticalRegion)
97 this.mutexHandle = mutexHandle;
98 this.inCriticalRegion = inCriticalRegion;
102 private static bool dummyBool;
115 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
116 [__DynamicallyInvokable]
117 public Mutex(
bool initiallyOwned,
string name, out
bool createdNew)
118 : this(initiallyOwned, name, out createdNew, (
MutexSecurity)null)
134 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
135 public unsafe
Mutex(
bool initiallyOwned,
string name, out
bool createdNew,
MutexSecurity mutexSecurity)
137 if (name !=
null && 260 < name.Length)
141 Win32Native.SECURITY_ATTRIBUTES sECURITY_ATTRIBUTES =
null;
142 if (mutexSecurity !=
null)
144 sECURITY_ATTRIBUTES =
new Win32Native.SECURITY_ATTRIBUTES();
145 sECURITY_ATTRIBUTES.nLength =
Marshal.
SizeOf(sECURITY_ATTRIBUTES);
146 byte[] securityDescriptorBinaryForm = mutexSecurity.GetSecurityDescriptorBinaryForm();
147 byte* ptr = stackalloc
byte[(int)checked(unchecked((ulong)(uint)securityDescriptorBinaryForm.Length) * 1uL)];
148 Buffer.Memcpy(ptr, 0, securityDescriptorBinaryForm, 0, securityDescriptorBinaryForm.Length);
149 sECURITY_ATTRIBUTES.pSecurityDescriptor = ptr;
151 CreateMutexWithGuaranteedCleanup(initiallyOwned, name, out createdNew, sECURITY_ATTRIBUTES);
155 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
156 internal Mutex(
bool initiallyOwned,
string name, out
bool createdNew, Win32Native.SECURITY_ATTRIBUTES secAttrs)
158 if (name !=
null && 260 < name.Length)
162 CreateMutexWithGuaranteedCleanup(initiallyOwned, name, out createdNew, secAttrs);
166 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
167 internal void CreateMutexWithGuaranteedCleanup(
bool initiallyOwned,
string name, out
bool createdNew, Win32Native.SECURITY_ATTRIBUTES secAttrs)
170 MutexCleanupInfo mutexCleanupInfo =
new MutexCleanupInfo(
null, inCriticalRegion:
false);
171 MutexTryCodeHelper mutexTryCodeHelper =
new MutexTryCodeHelper(initiallyOwned, mutexCleanupInfo, name, secAttrs,
this);
174 createdNew = mutexTryCodeHelper.m_newMutex;
179 private void MutexCleanupCode(
object userData,
bool exceptionThrown)
181 MutexCleanupInfo mutexCleanupInfo = (MutexCleanupInfo)userData;
182 if (hasThreadAffinity)
186 if (mutexCleanupInfo.mutexHandle !=
null && !mutexCleanupInfo.mutexHandle.IsInvalid)
188 if (mutexCleanupInfo.inCriticalRegion)
190 Win32Native.ReleaseMutex(mutexCleanupInfo.mutexHandle);
192 mutexCleanupInfo.mutexHandle.Dispose();
194 if (mutexCleanupInfo.inCriticalRegion)
196 Thread.EndCriticalRegion();
197 Thread.EndThreadAffinity();
211 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
212 [__DynamicallyInvokable]
213 public Mutex(
bool initiallyOwned,
string name)
214 : this(initiallyOwned, name, out dummyBool)
221 [SecuritySafeCritical]
222 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
223 [__DynamicallyInvokable]
225 : this(initiallyOwned, null, out dummyBool)
230 [SecuritySafeCritical]
231 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
232 [__DynamicallyInvokable]
234 : this(initiallyOwned: false, null, out dummyBool)
239 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
242 SetHandleInternal(handle);
243 hasThreadAffinity =
true;
258 [__DynamicallyInvokable]
280 switch (OpenExistingWorker(name, rights, out result))
282 case OpenExistingResult.NameNotFound:
284 case OpenExistingResult.NameInvalid:
286 case OpenExistingResult.PathNotFound:
287 __Error.WinIOError(3, name);
307 [__DynamicallyInvokable]
310 return OpenExistingWorker(name,
MutexRights.Modify |
MutexRights.Synchronize, out result) == OpenExistingResult.Success;
329 return OpenExistingWorker(name, rights, out result) == OpenExistingResult.Success;
333 private static OpenExistingResult OpenExistingWorker(
string name,
MutexRights rights, out
Mutex result)
339 if (name.Length == 0)
343 if (260 < name.Length)
345 throw new ArgumentException(Environment.GetResourceString(
"Argument_WaitHandleNameTooLong", name));
348 SafeWaitHandle safeWaitHandle = Win32Native.OpenMutex((
int)rights, inheritHandle:
false, name);
350 if (safeWaitHandle.IsInvalid)
353 if (2 == num || 123 == num)
355 return OpenExistingResult.NameNotFound;
359 return OpenExistingResult.PathNotFound;
361 if (name !=
null && name.Length != 0 && 6 == num)
363 return OpenExistingResult.NameInvalid;
365 __Error.WinIOError(num, name);
367 result =
new Mutex(safeWaitHandle);
368 return OpenExistingResult.Success;
374 [SecuritySafeCritical]
375 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
376 [__DynamicallyInvokable]
379 if (Win32Native.ReleaseMutex(safeWaitHandle))
389 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.MayFail)]
390 private static int CreateMutexHandle(
bool initiallyOwned,
string name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out
SafeWaitHandle mutexHandle)
396 mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name);
398 if (!mutexHandle.IsInvalid || num != 5)
410 Thread.BeginThreadAffinity();
413 mutexHandle = Win32Native.OpenMutex(1048577, inheritHandle:
false, name);
420 Thread.EndThreadAffinity();
439 [SecuritySafeCritical]
451 [SecuritySafeCritical]
454 if (mutexSecurity ==
null)
458 mutexSecurity.Persist(safeWaitHandle);
delegate void TryCode(object userData)
Represents a delegate to code that should be run in a try block..
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
Encapsulates operating system–specific objects that wait for exclusive access to shared resources.
The exception that is thrown when an attempt is made to open a system mutex, semaphore,...
SafeWaitHandle SafeWaitHandle
Gets or sets the native operating system handle.
Mutex(bool initiallyOwned, string name, out bool createdNew)
Initializes a new instance of the T:System.Threading.Mutex class with a Boolean value that indicates ...
static void ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, object userData)
Executes code using a T:System.Delegate while using another T:System.Delegate to execute additional c...
static Mutex OpenExisting(string name)
Opens the specified named mutex, if it already exists.
void ReleaseMutex()
Releases the T:System.Threading.Mutex once.
static int SizeOf(object structure)
Returns the unmanaged size of an object in bytes.
Mutex(bool initiallyOwned, string name)
Initializes a new instance of the T:System.Threading.Mutex class with a Boolean value that indicates ...
void SetAccessControl(MutexSecurity mutexSecurity)
Sets the access control security for a named system mutex.
Serves as the base class for application-defined exceptions.
A synchronization primitive that can also be used for interprocess synchronization.
static bool TryOpenExisting(string name, out Mutex result)
Opens the specified named mutex, if it already exists, and returns a value that indicates whether the...
static bool TryOpenExisting(string name, MutexRights rights, out Mutex result)
Opens the specified named mutex, if it already exists, with the desired security access,...
Mutex(bool initiallyOwned)
Initializes a new instance of the T:System.Threading.Mutex class with a Boolean value that indicates ...
Cer
Specifies a method's behavior when called within a constrained execution region.
SecurityAction
Specifies the security actions that can be performed using declarative security.
Provides information about, and means to manipulate, the current environment and platform....
Mutex()
Initializes a new instance of the T:System.Threading.Mutex class with default properties.
static void BeginCriticalRegion()
Notifies a host that execution is about to enter a region of code in which the effects of a thread ab...
unsafe Mutex(bool initiallyOwned, string name, out bool createdNew, MutexSecurity mutexSecurity)
Initializes a new instance of the T:System.Threading.Mutex class with a Boolean value that indicates ...
MutexSecurity GetAccessControl()
Gets a T:System.Security.AccessControl.MutexSecurity object that represents the access control securi...
static void PrepareConstrainedRegions()
Designates a body of code as a constrained execution region (CER).
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Represents the Windows access control security for a named mutex. This class cannot be inherited.
static void BeginThreadAffinity()
Notifies a host that managed code is about to execute instructions that depend on the identity of the...
static void EndCriticalRegion()
Notifies a host that execution is about to enter a region of code in which the effects of a thread ab...
MutexRights
Specifies the access control rights that can be applied to named system mutex objects.
The exception that is thrown when one of the arguments provided to a method is not valid.
delegate void CleanupCode(object userData, bool exceptionThrown)
Represents a method to run when an exception occurs.
static void EndThreadAffinity()
Notifies a host that managed code has finished executing instructions that depend on the identity of ...
Manipulates arrays of primitive types.
Consistency
Specifies a reliability contract.
static Mutex OpenExisting(string name, MutexRights rights)
Opens the specified named mutex, if it already exists, with the desired security access.
static int GetLastWin32Error()
Returns the error code returned by the last unmanaged function that was called using platform invoke ...
AccessControlSections
Specifies which sections of a security descriptor to save or load.
Provides a set of static methods and properties that provide support for compilers....
Creates and controls a thread, sets its priority, and gets its status.