Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / Mutex.cs / 1305376 / Mutex.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // //[....] /*============================================================================== ** ** Class: Mutex ** ** ** Purpose: synchronization primitive that can also be used for interprocess synchronization ** ** =============================================================================*/ namespace System.Threading { using System; using System.Threading; using System.Runtime.CompilerServices; using System.Security.Permissions; using System.IO; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; using System.Security.Principal; using System.Security; using System.Diagnostics.Contracts; #if !FEATURE_PAL && FEATURE_MACL using System.Security.AccessControl; #endif [HostProtection(Synchronization=true, ExternalThreading=true)] [ComVisible(true)] public sealed class Mutex : WaitHandle { static bool dummyBool; #if !FEATURE_PAL && FEATURE_MACL // Enables workaround for known OS bug at // http://support.microsoft.com/default.aspx?scid=kb;en-us;889318 // Calls to OpenMutex and CloseHandle on a mutex must essentially be serialized // to avoid a bug in which the mutex allows multiple entries. static Mutex s_ReservedMutex = null; // an arbitrary, reserved name. // const string c_ReservedMutexName = "Global\\CLR_RESERVED_MUTEX_NAME"; #endif [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public Mutex(bool initiallyOwned, String name, out bool createdNew) : this(initiallyOwned, name, out createdNew, null) { } #if FEATURE_PAL || !FEATURE_MACL public class MutexSecurity { } #endif [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public unsafe Mutex(bool initiallyOwned, String name, out bool createdNew, MutexSecurity mutexSecurity) { if(null != name && System.IO.Path.MAX_PATH < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name)); } Contract.EndContractBlock(); Win32Native.SECURITY_ATTRIBUTES secAttrs = null; #if !FEATURE_PAL && FEATURE_MACL // For ACL's, get the security descriptor from the MutexSecurity. if (mutexSecurity != null) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = mutexSecurity.GetSecurityDescriptorBinaryForm(); byte* pSecDescriptor = stackalloc byte[sd.Length]; Buffer.memcpy(sd, 0, pSecDescriptor, 0, sd.Length); secAttrs.pSecurityDescriptor = pSecDescriptor; } #endif RuntimeHelpers.CleanupCode cleanupCode = new RuntimeHelpers.CleanupCode(MutexCleanupCode); MutexCleanupInfo cleanupInfo = new MutexCleanupInfo(null, false); MutexTryCodeHelper tryCodeHelper = new MutexTryCodeHelper(initiallyOwned, cleanupInfo, name, secAttrs, this); RuntimeHelpers.TryCode tryCode = new RuntimeHelpers.TryCode(tryCodeHelper.MutexTryCode); RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup( tryCode, cleanupCode, cleanupInfo); createdNew = tryCodeHelper.m_newMutex; } internal class MutexTryCodeHelper { bool m_initiallyOwned; MutexCleanupInfo m_cleanupInfo; internal bool m_newMutex; String m_name; [System.Security.SecurityCritical /*auto-generated*/] Win32Native.SECURITY_ATTRIBUTES m_secAttrs; Mutex m_mutex; [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] internal MutexTryCodeHelper(bool initiallyOwned,MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex) { m_initiallyOwned = initiallyOwned; m_cleanupInfo = cleanupInfo; m_name = name; m_secAttrs = secAttrs; m_mutex = mutex; } [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] internal void MutexTryCode(object userData) { SafeWaitHandle mutexHandle = null; // try block RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { if (m_initiallyOwned) { m_cleanupInfo.inCriticalRegion = true; Thread.BeginThreadAffinity(); Thread.BeginCriticalRegion(); } } int errorCode = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { errorCode = CreateMutexHandle(m_initiallyOwned, m_name, m_secAttrs, out mutexHandle); } if (mutexHandle.IsInvalid) { mutexHandle.SetHandleAsInvalid(); if(null != m_name && 0 != m_name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode) throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", m_name)); __Error.WinIOError(errorCode, m_name); } m_newMutex = errorCode != Win32Native.ERROR_ALREADY_EXISTS; m_mutex.SetHandleInternal(mutexHandle); mutexHandle.SetAsMutex(); m_mutex.hasThreadAffinity = true; } } [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] private void MutexCleanupCode(Object userData, bool exceptionThrown) { MutexCleanupInfo cleanupInfo = (MutexCleanupInfo) userData; // If hasThreadAffinity isn't true, we've thrown an exception in the above try, and we must free the mutex // on this OS thread before ending our thread affninity. if(!hasThreadAffinity) { if (cleanupInfo.mutexHandle != null && !cleanupInfo.mutexHandle.IsInvalid) { if( cleanupInfo.inCriticalRegion) { Win32Native.ReleaseMutex(cleanupInfo.mutexHandle); } cleanupInfo.mutexHandle.Dispose(); } if( cleanupInfo.inCriticalRegion) { Thread.EndCriticalRegion(); Thread.EndThreadAffinity(); } } } internal class MutexCleanupInfo { [System.Security.SecurityCritical /*auto-generated*/] internal SafeWaitHandle mutexHandle; internal bool inCriticalRegion; [System.Security.SecurityCritical] // auto-generated internal MutexCleanupInfo(SafeWaitHandle mutexHandle, bool inCriticalRegion) { this.mutexHandle = mutexHandle; this.inCriticalRegion = inCriticalRegion; } } [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public Mutex(bool initiallyOwned, String name) : this(initiallyOwned, name, out dummyBool) { } [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public Mutex(bool initiallyOwned) : this(initiallyOwned, null, out dummyBool) { } [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public Mutex() : this(false, null, out dummyBool) { } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private Mutex(SafeWaitHandle handle) { SetHandleInternal(handle); handle.SetAsMutex(); hasThreadAffinity = true; } [System.Security.SecurityCritical] // auto-generated_required [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static Mutex OpenExisting(string name) { #if FEATURE_PAL || !FEATURE_MACL return OpenExisting(name, (MutexRights) 0); #else // FEATURE_PAL return OpenExisting(name, MutexRights.Modify | MutexRights.Synchronize); #endif // FEATURE_PAL } #if FEATURE_PAL || !FEATURE_MACL public enum MutexRights { } #endif [System.Security.SecurityCritical] // auto-generated_required [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static Mutex OpenExisting(string name, MutexRights rights) { if (name == null) { throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName")); } if(name.Length == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); } if(System.IO.Path.MAX_PATH < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name)); } Contract.EndContractBlock(); // To allow users to view & edit the ACL's, call OpenMutex // with parameters to allow us to view & edit the ACL. This will // fail if we don't have permission to view or edit the ACL's. // If that happens, ask for less permissions. #if !FEATURE_PAL && FEATURE_MACL SafeWaitHandle myHandle = Win32Native.OpenMutex((int) rights, false, name); #else SafeWaitHandle myHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name); #endif int errorCode = 0; if (myHandle.IsInvalid) { errorCode = Marshal.GetLastWin32Error(); if(Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode) { throw new WaitHandleCannotBeOpenedException(); } if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode) { throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name)); } // this is for passed through Win32Native Errors __Error.WinIOError(errorCode,name); } return new Mutex(myHandle); } // Note: To call ReleaseMutex, you must have an ACL granting you // MUTEX_MODIFY_STATE rights (0x0001). The other interesting value // in a Mutex's ACL is MUTEX_ALL_ACCESS (0x1F0001). [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public void ReleaseMutex() { if (Win32Native.ReleaseMutex(safeWaitHandle)) { Thread.EndCriticalRegion(); Thread.EndThreadAffinity(); } else { #if FEATURE_CORECLR throw new Exception(Environment.GetResourceString("Arg_SynchronizationLockException")); #else throw new ApplicationException(Environment.GetResourceString("Arg_SynchronizationLockException")); #endif // FEATURE_CORECLR } } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle) { int errorCode; bool fReservedMutexObtained = false; bool fAffinity = false; while(true) { mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name); errorCode = Marshal.GetLastWin32Error(); if( !mutexHandle.IsInvalid) { break; } if( errorCode == Win32Native.ERROR_ACCESS_DENIED) { // If a mutex with the name already exists, OS will try to open it with FullAccess. // It might fail if we don't have enough access. In that case, we try to open the mutex will modify and synchronize access. // RuntimeHelpers.PrepareConstrainedRegions(); try { try { } finally { Thread.BeginThreadAffinity(); fAffinity = true; } AcquireReservedMutex(ref fReservedMutexObtained); mutexHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name); if(!mutexHandle.IsInvalid) { errorCode = Win32Native.ERROR_ALREADY_EXISTS; } else { errorCode = Marshal.GetLastWin32Error(); } } finally { if (fReservedMutexObtained) ReleaseReservedMutex(); if (fAffinity) Thread.EndThreadAffinity(); } // There could be a ---- here, the other owner of the mutex can free the mutex, // We need to retry creation in that case. if( errorCode != Win32Native.ERROR_FILE_NOT_FOUND) { if( errorCode == Win32Native.ERROR_SUCCESS) { errorCode = Win32Native.ERROR_ALREADY_EXISTS; } break; } } else { break; } } return errorCode; } #if !FEATURE_PAL && FEATURE_MACL [System.Security.SecuritySafeCritical] // auto-generated public MutexSecurity GetAccessControl() { return new MutexSecurity(safeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group); } [System.Security.SecuritySafeCritical] // auto-generated public void SetAccessControl(MutexSecurity mutexSecurity) { if (mutexSecurity == null) throw new ArgumentNullException("mutexSecurity"); Contract.EndContractBlock(); mutexSecurity.Persist(safeWaitHandle); } #endif // Enables workaround for known OS bug at // http://support.microsoft.com/default.aspx?scid=kb;en-us;889318 // One machine-wide mutex serializes all OpenMutex and CloseHandle operations. [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [SecurityPermission(SecurityAction.Assert, ControlPrincipal = true)] internal static unsafe void AcquireReservedMutex(ref bool bHandleObtained) { #if !FEATURE_PAL && FEATURE_MACL SafeWaitHandle mutexHandle = null; int errorCode; bHandleObtained = false; if (!Environment.IsW2k3) { return; } if (s_ReservedMutex == null) { // Create a maximally-permissive security descriptor, to ensure we never get an // ACCESS_DENIED error when calling CreateMutex MutexSecurity sec = new MutexSecurity(); SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); sec.AddAccessRule(new MutexAccessRule(everyoneSid, MutexRights.FullControl, AccessControlType.Allow)); // For ACL's, get the security descriptor from the MutexSecurity. Win32Native.SECURITY_ATTRIBUTES secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = sec.GetSecurityDescriptorBinaryForm(); byte * bytesOnStack = stackalloc byte[sd.Length]; Buffer.memcpy(sd, 0, bytesOnStack, 0, sd.Length); secAttrs.pSecurityDescriptor = bytesOnStack; RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { mutexHandle = Win32Native.CreateMutex(secAttrs, false, c_ReservedMutexName); // need to set specially, since this mutex cannot lock on itself while closing itself. mutexHandle.SetAsReservedMutex(); } errorCode = Marshal.GetLastWin32Error(); if (mutexHandle.IsInvalid) { mutexHandle.SetHandleAsInvalid(); __Error.WinIOError(errorCode, c_ReservedMutexName); } Mutex m = new Mutex(mutexHandle); Interlocked.CompareExchange(ref s_ReservedMutex, m, null); } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { try { s_ReservedMutex.WaitOne(); bHandleObtained = true; } catch (AbandonedMutexException) { // we don't care if another process holding the Mutex was killed bHandleObtained = true; } } #else bHandleObtained = true; #endif } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal static void ReleaseReservedMutex() { #if !FEATURE_PAL && FEATURE_MACL if (!Environment.IsW2k3) { return; } Contract.Assert(s_ReservedMutex != null, "ReleaseReservedMutex called without prior call to AcquireReservedMutex!"); s_ReservedMutex.ReleaseMutex(); #endif } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // //[....] /*============================================================================== ** ** Class: Mutex ** ** ** Purpose: synchronization primitive that can also be used for interprocess synchronization ** ** =============================================================================*/ namespace System.Threading { using System; using System.Threading; using System.Runtime.CompilerServices; using System.Security.Permissions; using System.IO; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; using System.Security.Principal; using System.Security; using System.Diagnostics.Contracts; #if !FEATURE_PAL && FEATURE_MACL using System.Security.AccessControl; #endif [HostProtection(Synchronization=true, ExternalThreading=true)] [ComVisible(true)] public sealed class Mutex : WaitHandle { static bool dummyBool; #if !FEATURE_PAL && FEATURE_MACL // Enables workaround for known OS bug at // http://support.microsoft.com/default.aspx?scid=kb;en-us;889318 // Calls to OpenMutex and CloseHandle on a mutex must essentially be serialized // to avoid a bug in which the mutex allows multiple entries. static Mutex s_ReservedMutex = null; // an arbitrary, reserved name. // const string c_ReservedMutexName = "Global\\CLR_RESERVED_MUTEX_NAME"; #endif [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public Mutex(bool initiallyOwned, String name, out bool createdNew) : this(initiallyOwned, name, out createdNew, null) { } #if FEATURE_PAL || !FEATURE_MACL public class MutexSecurity { } #endif [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public unsafe Mutex(bool initiallyOwned, String name, out bool createdNew, MutexSecurity mutexSecurity) { if(null != name && System.IO.Path.MAX_PATH < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name)); } Contract.EndContractBlock(); Win32Native.SECURITY_ATTRIBUTES secAttrs = null; #if !FEATURE_PAL && FEATURE_MACL // For ACL's, get the security descriptor from the MutexSecurity. if (mutexSecurity != null) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = mutexSecurity.GetSecurityDescriptorBinaryForm(); byte* pSecDescriptor = stackalloc byte[sd.Length]; Buffer.memcpy(sd, 0, pSecDescriptor, 0, sd.Length); secAttrs.pSecurityDescriptor = pSecDescriptor; } #endif RuntimeHelpers.CleanupCode cleanupCode = new RuntimeHelpers.CleanupCode(MutexCleanupCode); MutexCleanupInfo cleanupInfo = new MutexCleanupInfo(null, false); MutexTryCodeHelper tryCodeHelper = new MutexTryCodeHelper(initiallyOwned, cleanupInfo, name, secAttrs, this); RuntimeHelpers.TryCode tryCode = new RuntimeHelpers.TryCode(tryCodeHelper.MutexTryCode); RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup( tryCode, cleanupCode, cleanupInfo); createdNew = tryCodeHelper.m_newMutex; } internal class MutexTryCodeHelper { bool m_initiallyOwned; MutexCleanupInfo m_cleanupInfo; internal bool m_newMutex; String m_name; [System.Security.SecurityCritical /*auto-generated*/] Win32Native.SECURITY_ATTRIBUTES m_secAttrs; Mutex m_mutex; [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] internal MutexTryCodeHelper(bool initiallyOwned,MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex) { m_initiallyOwned = initiallyOwned; m_cleanupInfo = cleanupInfo; m_name = name; m_secAttrs = secAttrs; m_mutex = mutex; } [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] internal void MutexTryCode(object userData) { SafeWaitHandle mutexHandle = null; // try block RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { if (m_initiallyOwned) { m_cleanupInfo.inCriticalRegion = true; Thread.BeginThreadAffinity(); Thread.BeginCriticalRegion(); } } int errorCode = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { errorCode = CreateMutexHandle(m_initiallyOwned, m_name, m_secAttrs, out mutexHandle); } if (mutexHandle.IsInvalid) { mutexHandle.SetHandleAsInvalid(); if(null != m_name && 0 != m_name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode) throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", m_name)); __Error.WinIOError(errorCode, m_name); } m_newMutex = errorCode != Win32Native.ERROR_ALREADY_EXISTS; m_mutex.SetHandleInternal(mutexHandle); mutexHandle.SetAsMutex(); m_mutex.hasThreadAffinity = true; } } [System.Security.SecurityCritical] // auto-generated [PrePrepareMethod] private void MutexCleanupCode(Object userData, bool exceptionThrown) { MutexCleanupInfo cleanupInfo = (MutexCleanupInfo) userData; // If hasThreadAffinity isn't true, we've thrown an exception in the above try, and we must free the mutex // on this OS thread before ending our thread affninity. if(!hasThreadAffinity) { if (cleanupInfo.mutexHandle != null && !cleanupInfo.mutexHandle.IsInvalid) { if( cleanupInfo.inCriticalRegion) { Win32Native.ReleaseMutex(cleanupInfo.mutexHandle); } cleanupInfo.mutexHandle.Dispose(); } if( cleanupInfo.inCriticalRegion) { Thread.EndCriticalRegion(); Thread.EndThreadAffinity(); } } } internal class MutexCleanupInfo { [System.Security.SecurityCritical /*auto-generated*/] internal SafeWaitHandle mutexHandle; internal bool inCriticalRegion; [System.Security.SecurityCritical] // auto-generated internal MutexCleanupInfo(SafeWaitHandle mutexHandle, bool inCriticalRegion) { this.mutexHandle = mutexHandle; this.inCriticalRegion = inCriticalRegion; } } [System.Security.SecurityCritical] // auto-generated_required [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public Mutex(bool initiallyOwned, String name) : this(initiallyOwned, name, out dummyBool) { } [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public Mutex(bool initiallyOwned) : this(initiallyOwned, null, out dummyBool) { } [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public Mutex() : this(false, null, out dummyBool) { } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private Mutex(SafeWaitHandle handle) { SetHandleInternal(handle); handle.SetAsMutex(); hasThreadAffinity = true; } [System.Security.SecurityCritical] // auto-generated_required [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static Mutex OpenExisting(string name) { #if FEATURE_PAL || !FEATURE_MACL return OpenExisting(name, (MutexRights) 0); #else // FEATURE_PAL return OpenExisting(name, MutexRights.Modify | MutexRights.Synchronize); #endif // FEATURE_PAL } #if FEATURE_PAL || !FEATURE_MACL public enum MutexRights { } #endif [System.Security.SecurityCritical] // auto-generated_required [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static Mutex OpenExisting(string name, MutexRights rights) { if (name == null) { throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName")); } if(name.Length == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); } if(System.IO.Path.MAX_PATH < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name)); } Contract.EndContractBlock(); // To allow users to view & edit the ACL's, call OpenMutex // with parameters to allow us to view & edit the ACL. This will // fail if we don't have permission to view or edit the ACL's. // If that happens, ask for less permissions. #if !FEATURE_PAL && FEATURE_MACL SafeWaitHandle myHandle = Win32Native.OpenMutex((int) rights, false, name); #else SafeWaitHandle myHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name); #endif int errorCode = 0; if (myHandle.IsInvalid) { errorCode = Marshal.GetLastWin32Error(); if(Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode) { throw new WaitHandleCannotBeOpenedException(); } if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode) { throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name)); } // this is for passed through Win32Native Errors __Error.WinIOError(errorCode,name); } return new Mutex(myHandle); } // Note: To call ReleaseMutex, you must have an ACL granting you // MUTEX_MODIFY_STATE rights (0x0001). The other interesting value // in a Mutex's ACL is MUTEX_ALL_ACCESS (0x1F0001). [System.Security.SecuritySafeCritical] // auto-generated [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public void ReleaseMutex() { if (Win32Native.ReleaseMutex(safeWaitHandle)) { Thread.EndCriticalRegion(); Thread.EndThreadAffinity(); } else { #if FEATURE_CORECLR throw new Exception(Environment.GetResourceString("Arg_SynchronizationLockException")); #else throw new ApplicationException(Environment.GetResourceString("Arg_SynchronizationLockException")); #endif // FEATURE_CORECLR } } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle) { int errorCode; bool fReservedMutexObtained = false; bool fAffinity = false; while(true) { mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name); errorCode = Marshal.GetLastWin32Error(); if( !mutexHandle.IsInvalid) { break; } if( errorCode == Win32Native.ERROR_ACCESS_DENIED) { // If a mutex with the name already exists, OS will try to open it with FullAccess. // It might fail if we don't have enough access. In that case, we try to open the mutex will modify and synchronize access. // RuntimeHelpers.PrepareConstrainedRegions(); try { try { } finally { Thread.BeginThreadAffinity(); fAffinity = true; } AcquireReservedMutex(ref fReservedMutexObtained); mutexHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name); if(!mutexHandle.IsInvalid) { errorCode = Win32Native.ERROR_ALREADY_EXISTS; } else { errorCode = Marshal.GetLastWin32Error(); } } finally { if (fReservedMutexObtained) ReleaseReservedMutex(); if (fAffinity) Thread.EndThreadAffinity(); } // There could be a ---- here, the other owner of the mutex can free the mutex, // We need to retry creation in that case. if( errorCode != Win32Native.ERROR_FILE_NOT_FOUND) { if( errorCode == Win32Native.ERROR_SUCCESS) { errorCode = Win32Native.ERROR_ALREADY_EXISTS; } break; } } else { break; } } return errorCode; } #if !FEATURE_PAL && FEATURE_MACL [System.Security.SecuritySafeCritical] // auto-generated public MutexSecurity GetAccessControl() { return new MutexSecurity(safeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group); } [System.Security.SecuritySafeCritical] // auto-generated public void SetAccessControl(MutexSecurity mutexSecurity) { if (mutexSecurity == null) throw new ArgumentNullException("mutexSecurity"); Contract.EndContractBlock(); mutexSecurity.Persist(safeWaitHandle); } #endif // Enables workaround for known OS bug at // http://support.microsoft.com/default.aspx?scid=kb;en-us;889318 // One machine-wide mutex serializes all OpenMutex and CloseHandle operations. [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [SecurityPermission(SecurityAction.Assert, ControlPrincipal = true)] internal static unsafe void AcquireReservedMutex(ref bool bHandleObtained) { #if !FEATURE_PAL && FEATURE_MACL SafeWaitHandle mutexHandle = null; int errorCode; bHandleObtained = false; if (!Environment.IsW2k3) { return; } if (s_ReservedMutex == null) { // Create a maximally-permissive security descriptor, to ensure we never get an // ACCESS_DENIED error when calling CreateMutex MutexSecurity sec = new MutexSecurity(); SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); sec.AddAccessRule(new MutexAccessRule(everyoneSid, MutexRights.FullControl, AccessControlType.Allow)); // For ACL's, get the security descriptor from the MutexSecurity. Win32Native.SECURITY_ATTRIBUTES secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = sec.GetSecurityDescriptorBinaryForm(); byte * bytesOnStack = stackalloc byte[sd.Length]; Buffer.memcpy(sd, 0, bytesOnStack, 0, sd.Length); secAttrs.pSecurityDescriptor = bytesOnStack; RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { mutexHandle = Win32Native.CreateMutex(secAttrs, false, c_ReservedMutexName); // need to set specially, since this mutex cannot lock on itself while closing itself. mutexHandle.SetAsReservedMutex(); } errorCode = Marshal.GetLastWin32Error(); if (mutexHandle.IsInvalid) { mutexHandle.SetHandleAsInvalid(); __Error.WinIOError(errorCode, c_ReservedMutexName); } Mutex m = new Mutex(mutexHandle); Interlocked.CompareExchange(ref s_ReservedMutex, m, null); } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { try { s_ReservedMutex.WaitOne(); bHandleObtained = true; } catch (AbandonedMutexException) { // we don't care if another process holding the Mutex was killed bHandleObtained = true; } } #else bHandleObtained = true; #endif } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal static void ReleaseReservedMutex() { #if !FEATURE_PAL && FEATURE_MACL if (!Environment.IsW2k3) { return; } Contract.Assert(s_ReservedMutex != null, "ReleaseReservedMutex called without prior call to AcquireReservedMutex!"); s_ReservedMutex.ReleaseMutex(); #endif } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NullableDoubleMinMaxAggregationOperator.cs
- IdentityHolder.cs
- OutKeywords.cs
- LayoutEditorPart.cs
- mda.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- translator.cs
- FullTrustAssembliesSection.cs
- FragmentQueryKB.cs
- TableRowCollection.cs
- XamlReader.cs
- AdapterUtil.cs
- shaperfactoryquerycachekey.cs
- TimeIntervalCollection.cs
- SqlConnectionHelper.cs
- ZipIOLocalFileDataDescriptor.cs
- OracleException.cs
- ResourceDescriptionAttribute.cs
- PolyLineSegment.cs
- ReflectionTypeLoadException.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- SecurityVerifiedMessage.cs
- PagesSection.cs
- HwndSubclass.cs
- MappingModelBuildProvider.cs
- NavigationHelper.cs
- WmlLinkAdapter.cs
- DataException.cs
- AdapterDictionary.cs
- SqlClientMetaDataCollectionNames.cs
- Pen.cs
- CommandManager.cs
- Inline.cs
- CodeDomDecompiler.cs
- TextEndOfParagraph.cs
- DayRenderEvent.cs
- WebPartCloseVerb.cs
- CatalogPartCollection.cs
- JsonObjectDataContract.cs
- RunClient.cs
- String.cs
- ArrayWithOffset.cs
- RoleService.cs
- SubtreeProcessor.cs
- SamlAttributeStatement.cs
- LongMinMaxAggregationOperator.cs
- DataGridViewCell.cs
- SqlDataSourceCommandEventArgs.cs
- XPathAncestorQuery.cs
- HttpBrowserCapabilitiesWrapper.cs
- AutomationEvent.cs
- ProcessHostServerConfig.cs
- CanonicalFontFamilyReference.cs
- LicenseManager.cs
- DiscoveryDocumentSearchPattern.cs
- SafeViewOfFileHandle.cs
- XmlNamespaceDeclarationsAttribute.cs
- BaseDataListPage.cs
- HttpModuleActionCollection.cs
- SimpleType.cs
- ErrorTableItemStyle.cs
- WindowPattern.cs
- TypedTableBase.cs
- GenericTextProperties.cs
- TranslateTransform3D.cs
- SecurityVersion.cs
- WebHostUnsafeNativeMethods.cs
- JsonFormatReaderGenerator.cs
- GroupItemAutomationPeer.cs
- CircleHotSpot.cs
- CategoryAttribute.cs
- UniqueConstraint.cs
- StoreContentChangedEventArgs.cs
- WindowsComboBox.cs
- DayRenderEvent.cs
- CorrelationTokenInvalidatedHandler.cs
- XsltOutput.cs
- ViewEventArgs.cs
- SchemaNotation.cs
- WeakReferenceEnumerator.cs
- MissingSatelliteAssemblyException.cs
- InvokeProviderWrapper.cs
- _SSPIWrapper.cs
- __Filters.cs
- CodeNamespaceCollection.cs
- CollectionViewGroupRoot.cs
- BaseParaClient.cs
- HtmlUtf8RawTextWriter.cs
- EventListenerClientSide.cs
- HelpEvent.cs
- IntSumAggregationOperator.cs
- ProcessModule.cs
- PropertyEmitter.cs
- CodeValidator.cs
- DbException.cs
- WeakReferenceEnumerator.cs
- Window.cs
- DataGridViewCellLinkedList.cs
- MaskInputRejectedEventArgs.cs
- TextElementEnumerator.cs