[System.Security.SecuritySafeCritical] // auto-generated public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) { if (waitHandles == null) { throw new ArgumentNullException("waitHandles", Environment.GetResourceString("ArgumentNull_Waithandles")); } if (waitHandles.Length == 0) { // // Some history: in CLR 1.0 and 1.1, we threw ArgumentException in this case, which was correct. // Somehow, in 2.0, this became ArgumentNullException. This was not fixed until Silverlight 2, // which went back to ArgumentException. // // Now we're in a bit of a bind. Backward-compatibility requires us to keep throwing ArgumentException // in CoreCLR, and ArgumentNullException in the desktop CLR. This is ugly, but so is breaking // user code. // #if FEATURE_CORECLR throw new ArgumentException(Environment.GetResourceString("Argument_EmptyWaithandleArray")); #else throw new ArgumentNullException("waitHandles", Environment.GetResourceString("Argument_EmptyWaithandleArray")); #endif } if (waitHandles.Length > MAX_WAITHANDLES) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_MaxWaitHandles")); } if (-1 > millisecondsTimeout) { throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } Contract.EndContractBlock(); WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length]; for (int i = 0; i < waitHandles.Length; i++) { WaitHandle waitHandle = waitHandles[i]; if (waitHandle == null) { throw new ArgumentNullException("waitHandles[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayElement")); } #if FEATURE_REMOTING if (RemotingServices.IsTransparentProxy(waitHandle)) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy")); } #endif internalWaitHandles[i] = waitHandle; } #if _DEBUG // make sure we do not use waitHandles any more. waitHandles = null; #endif int ret = WaitMultiple(internalWaitHandles, millisecondsTimeout, exitContext, true /* waitall*/); if (AppDomainPauseManager.IsPaused) { AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS(); } if ((WAIT_ABANDONED <= ret) && (WAIT_ABANDONED + internalWaitHandles.Length > ret)) { //In the case of WaitAll the OS will only provide the // information that mutex was abandoned. // It won't tell us which one. So we can't set the Index or provide access to the Mutex ThrowAbandonedMutexException(); } GC.KeepAlive(internalWaitHandles); return(ret != WaitTimeout); }
public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) { if (waitHandles == null) { throw new ArgumentNullException("waitHandles", Environment.GetResourceString("ArgumentNull_Waithandles")); } if (waitHandles.Length == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyWaithandleArray")); } if (MAX_WAITHANDLES < waitHandles.Length) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_MaxWaitHandles")); } if (-1 > millisecondsTimeout) { throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); } Contract.EndContractBlock(); WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length]; for (int i = 0; i < waitHandles.Length; i++) { WaitHandle waitHandle = waitHandles[i]; if (waitHandle == null) { throw new ArgumentNullException("waitHandles[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayElement")); } #if FEATURE_REMOTING if (RemotingServices.IsTransparentProxy(waitHandle)) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy")); } #endif internalWaitHandles[i] = waitHandle; } #if _DEBUG // make sure we do not use waitHandles any more. waitHandles = null; #endif int ret = WaitMultiple(internalWaitHandles, millisecondsTimeout, exitContext, false /* waitany*/); if (AppDomainPauseManager.IsPaused) { AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS(); } if ((WAIT_ABANDONED <= ret) && (WAIT_ABANDONED + internalWaitHandles.Length > ret)) { int mutexIndex = ret - WAIT_ABANDONED; if (0 <= mutexIndex && mutexIndex < internalWaitHandles.Length) { ThrowAbandonedMutexException(mutexIndex, internalWaitHandles[mutexIndex]); } else { ThrowAbandonedMutexException(); } } GC.KeepAlive(internalWaitHandles); return(ret); }
private static OpenExistingResult OpenExistingWorker(string name, MutexRights rights, out Mutex result) { #if PLATFORM_UNIX throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives")); #else 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.MaxPath < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", name)); } Contract.EndContractBlock(); result = null; #if FEATURE_LEGACYNETCF if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) { name = WinCEObjectNameQuirk(name); } #endif // 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_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) { return(OpenExistingResult.NameNotFound); } if (Win32Native.ERROR_PATH_NOT_FOUND == errorCode) { return(OpenExistingResult.PathNotFound); } if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode) { return(OpenExistingResult.NameInvalid); } // this is for passed through Win32Native Errors __Error.WinIOError(errorCode, name); } result = new Mutex(myHandle); return(OpenExistingResult.Success); #endif }