We need you! We're working hard on the next version of Developer Fusion -
Let us know what you think we should be up to!
- 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;
-
-
- [HostProtection(Synchronization = true, ExternalThreading = true)]
- [ComVisible(true)]
- public sealed class Mutex : WaitHandle
- {
- static bool dummyBool;
-
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- [ResourceExposure(ResourceScope.None)]
- [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
- public Mutex(bool initiallyOwned, string name, out bool createdNew)
- {
- if (null != name && System.IO.Path.MAX_PATH < name.Length) {
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", name));
- }
- Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
- SafeWaitHandle mutexHandle = null;
- bool newMutex = false;
- RuntimeHelpers.CleanupCode cleanupCode = new RuntimeHelpers.CleanupCode(MutexCleanupCode);
- MutexCleanupInfo cleanupInfo = new MutexCleanupInfo(mutexHandle, false);
- RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(delegate(object userData)
- {
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- }
- finally {
- if (initiallyOwned) {
- cleanupInfo.inCriticalRegion = true;
- Thread.BeginThreadAffinity();
- Thread.BeginCriticalRegion();
- }
- }
-
- int errorCode = 0;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- }
- finally {
- errorCode = CreateMutexHandle(initiallyOwned, name, secAttrs, out mutexHandle);
- }
-
- if (mutexHandle.IsInvalid) {
- mutexHandle.SetHandleAsInvalid();
- if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
- throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name));
- __Error.WinIOError(errorCode, name);
- }
- newMutex = errorCode != Win32Native.ERROR_ALREADY_EXISTS;
- SetHandleInternal(mutexHandle);
- mutexHandle.SetAsMutex();
-
- hasThreadAffinity = true;
-
- }
- , cleanupCode, cleanupInfo);
- createdNew = newMutex;
-
- }
-
- [PrePrepareMethod()]
- private void MutexCleanupCode(object userData, bool exceptionThrown)
- {
- MutexCleanupInfo cleanupInfo = (MutexCleanupInfo)userData;
-
-
-
- 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
- {
- internal SafeWaitHandle mutexHandle;
- internal bool inCriticalRegion;
- internal MutexCleanupInfo(SafeWaitHandle mutexHandle, bool inCriticalRegion)
- {
- this.mutexHandle = mutexHandle;
- this.inCriticalRegion = inCriticalRegion;
- }
- }
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- [ResourceExposure(ResourceScope.Machine)]
- [ResourceConsumption(ResourceScope.Machine)]
- public Mutex(bool initiallyOwned, string name) : this(initiallyOwned, name, out dummyBool)
- {
- }
-
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- [ResourceExposure(ResourceScope.None)]
- [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
- public Mutex(bool initiallyOwned) : this(initiallyOwned, null, out dummyBool)
- {
- }
-
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- [ResourceExposure(ResourceScope.None)]
- [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
- public Mutex() : this(false, null, out dummyBool)
- {
- }
-
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- private Mutex(SafeWaitHandle handle)
- {
- SetHandleInternal(handle);
- handle.SetAsMutex();
- hasThreadAffinity = true;
- }
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- [ResourceExposure(ResourceScope.Machine)]
- [ResourceConsumption(ResourceScope.Machine)]
- public static Mutex OpenExisting(string name)
- {
- 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));
- }
-
-
-
-
-
-
- SafeWaitHandle myHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name);
-
- 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));
- }
-
-
- __Error.WinIOError(errorCode, name);
- }
-
- return new Mutex(myHandle);
- }
-
-
-
-
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- public void ReleaseMutex()
- {
- if (Win32Native.ReleaseMutex(safeWaitHandle)) {
- Thread.EndCriticalRegion();
- Thread.EndThreadAffinity();
- }
- else {
- throw new ApplicationException(Environment.GetResourceString("Arg_SynchronizationLockException"));
- }
- }
-
- [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) {
-
-
-
-
- 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();
- }
-
-
-
- if (errorCode != Win32Native.ERROR_FILE_NOT_FOUND) {
- if (errorCode == Win32Native.ERROR_SUCCESS) {
- errorCode = Win32Native.ERROR_ALREADY_EXISTS;
- }
- break;
- }
- }
- else {
- break;
- }
- }
- return errorCode;
- }
-
-
-
-
-
-
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- unsafe static internal void AcquireReservedMutex(ref bool bHandleObtained)
- {
- bHandleObtained = true;
- }
-
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- static internal void ReleaseReservedMutex()
- {
- }
-
- }
- }