public unsafe Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity) #endif { if (initialCount < 0) { throw new ArgumentOutOfRangeException("initialCount", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNumRequired)); } if (maximumCount < 1) { throw new ArgumentOutOfRangeException("maximumCount", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNumRequired)); } if (initialCount > maximumCount) { throw new ArgumentException(SR.GetString(SR.Argument_SemaphoreInitialMaximum)); } if (null != name && MAX_PATH < name.Length) { throw new ArgumentException(SR.GetString(SR.Argument_WaitHandleNameTooLong)); } SafeWaitHandle myHandle; #if !FEATURE_PAL && !FEATURE_NETCORE // For ACL's, get the security descriptor from the SemaphoreSecurity. if (semaphoreSecurity != null) { NativeMethods.SECURITY_ATTRIBUTES secAttrs = null; secAttrs = new NativeMethods.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = semaphoreSecurity.GetSecurityDescriptorBinaryForm(); fixed(byte *pSecDescriptor = sd) { secAttrs.lpSecurityDescriptor = new SafeLocalMemHandle((IntPtr)pSecDescriptor, false); myHandle = SafeNativeMethods.CreateSemaphore(secAttrs, initialCount, maximumCount, name); } } else { #endif myHandle = SafeNativeMethods.CreateSemaphore(null, initialCount, maximumCount, name); #if !FEATURE_PAL && !FEATURE_NETCORE } #endif int errorCode = Marshal.GetLastWin32Error(); if (myHandle.IsInvalid) { if (null != name && 0 != name.Length && NativeMethods.ERROR_INVALID_HANDLE == errorCode) { throw new WaitHandleCannotBeOpenedException(SR.GetString(SR.WaitHandleCannotBeOpenedException_InvalidHandle, name)); } InternalResources.WinIOError(); } createdNew = errorCode != NativeMethods.ERROR_ALREADY_EXISTS; this.SafeWaitHandle = myHandle; }
/// <summary>Gets or creates an <see cref="Semaphore" /> instance, allowing a <see cref="SemaphoreSecurity " /> instance to be optionally specified to set it during the event creation.</summary> /// <param name="initialCount">The initial number of requests for the semaphore that can be satisfied concurrently.</param> /// <param name="maximumCount">The maximum number of requests for the semaphore that can be satisfied concurrently.</param> /// <param name="name">Optional argument to create a system semaphore. Set to <see langword="null" /> or <see cref="string.Empty" /> to create a local semaphore.</param> /// <param name="createdNew">When this method returns, this argument is always set to <see langword="true" /> if a local semaphore is created; that is, when <paramref name="name" /> is <see langword="null" /> or <see cref="string.Empty" />. If <paramref name="name" /> has a valid, non-empty value, this argument is set to <see langword="true" /> when the system semaphore is created, or it is set to <see langword="false" /> if an existing system semaphore is found with that name. This parameter is passed uninitialized.</param> /// <param name="semaphoreSecurity">The optional semaphore access control security to apply.</param> /// <returns>An object that represents a system semaphore, if named, or a local semaphore, if nameless.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="initialCount" /> is a negative number. /// -or- /// <paramref name="maximumCount" /> is not a positive number.</exception> /// <exception cref="ArgumentException"><paramref name="initialCount" /> is greater than <paramref name="maximumCount" />.</exception> /// <exception cref="WaitHandleCannotBeOpenedException">A semaphore handle with the system-wide name '<paramref name="name" />' cannot be created. A semaphore handle of a different type might have the same name.</exception> public static unsafe Semaphore Create(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity) { if (semaphoreSecurity == null) { return(new Semaphore(initialCount, maximumCount, name, out createdNew)); } if (initialCount < 0) { throw new ArgumentOutOfRangeException(nameof(initialCount), SR.ArgumentOutOfRange_NeedNonNegNum); } if (maximumCount < 1) { throw new ArgumentOutOfRangeException(nameof(maximumCount), SR.ArgumentOutOfRange_NeedPosNum); } if (initialCount > maximumCount) { throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum); } fixed(byte *pSecurityDescriptor = semaphoreSecurity.GetSecurityDescriptorBinaryForm()) { var secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES { nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES), lpSecurityDescriptor = (IntPtr)pSecurityDescriptor }; SafeWaitHandle handle = Interop.Kernel32.CreateSemaphoreEx( (IntPtr)(&secAttrs), initialCount, maximumCount, name, 0, // This parameter is reserved and must be 0. (uint)SemaphoreRights.FullControl // Equivalent to SEMAPHORE_ALL_ACCESS ); ValidateHandle(handle, name, out createdNew); Semaphore semaphore = new Semaphore(initialCount, maximumCount); SafeWaitHandle old = semaphore.SafeWaitHandle; semaphore.SafeWaitHandle = handle; old.Dispose(); return(semaphore); } }
public unsafe Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity) { SafeWaitHandle handle; if (initialCount < 0) { throw new ArgumentOutOfRangeException("initialCount", SR.GetString("ArgumentOutOfRange_NeedNonNegNumRequired")); } if (maximumCount < 1) { throw new ArgumentOutOfRangeException("maximumCount", SR.GetString("ArgumentOutOfRange_NeedNonNegNumRequired")); } if (initialCount > maximumCount) { throw new ArgumentException(SR.GetString("Argument_SemaphoreInitialMaximum")); } if ((name != null) && (MAX_PATH < name.Length)) { throw new ArgumentException(SR.GetString("Argument_WaitHandleNameTooLong")); } if (semaphoreSecurity != null) { Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES structure = null; structure = new Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(structure) }; fixed(byte *numRef = semaphoreSecurity.GetSecurityDescriptorBinaryForm()) { structure.lpSecurityDescriptor = new SafeLocalMemHandle((IntPtr)numRef, false); handle = Microsoft.Win32.SafeNativeMethods.CreateSemaphore(structure, initialCount, maximumCount, name); } } else { handle = Microsoft.Win32.SafeNativeMethods.CreateSemaphore(null, initialCount, maximumCount, name); } int num = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { if (((name != null) && (name.Length != 0)) && (6 == num)) { throw new WaitHandleCannotBeOpenedException(SR.GetString("WaitHandleCannotBeOpenedException_InvalidHandle", new object[] { name })); } InternalResources.WinIOError(); } createdNew = num != 0xb7; base.SafeWaitHandle = handle; }