mscorlib(4.0.0.0) API with additions
Semaphore.cs
1 using Microsoft.Win32;
2 using Microsoft.Win32.SafeHandles;
3 using System.IO.Ports;
6 using System.Security;
9 
10 namespace System.Threading
11 {
13  [ComVisible(false)]
14  [global::__DynamicallyInvokable]
15  [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
16  public sealed class Semaphore : WaitHandle
17  {
18  private new enum OpenExistingResult
19  {
20  Success,
21  NameNotFound,
22  PathNotFound,
23  NameInvalid
24  }
25 
26  private const int MAX_PATH = 260;
27 
36  [SecuritySafeCritical]
37  [global::__DynamicallyInvokable]
38  public Semaphore(int initialCount, int maximumCount)
39  : this(initialCount, maximumCount, null)
40  {
41  }
42 
56  [global::__DynamicallyInvokable]
57  [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
58  public Semaphore(int initialCount, int maximumCount, string name)
59  {
60  if (initialCount < 0)
61  {
62  throw new ArgumentOutOfRangeException("initialCount", SR.GetString("ArgumentOutOfRange_NeedNonNegNumRequired"));
63  }
64  if (maximumCount < 1)
65  {
66  throw new ArgumentOutOfRangeException("maximumCount", SR.GetString("ArgumentOutOfRange_NeedPosNum"));
67  }
68  if (initialCount > maximumCount)
69  {
70  throw new ArgumentException(SR.GetString("Argument_SemaphoreInitialMaximum"));
71  }
72  if (name != null && 260 < name.Length)
73  {
74  throw new ArgumentException(SR.GetString("Argument_WaitHandleNameTooLong"));
75  }
76  SafeWaitHandle safeWaitHandle = Microsoft.Win32.SafeNativeMethods.CreateSemaphore(null, initialCount, maximumCount, name);
77  if (safeWaitHandle.IsInvalid)
78  {
79  int lastWin32Error = Marshal.GetLastWin32Error();
80  if (name != null && name.Length != 0 && 6 == lastWin32Error)
81  {
82  throw new WaitHandleCannotBeOpenedException(SR.GetString("WaitHandleCannotBeOpenedException_InvalidHandle", name));
83  }
84  InternalResources.WinIOError();
85  }
86  base.SafeWaitHandle = safeWaitHandle;
87  }
88 
103  [global::__DynamicallyInvokable]
104  [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
105  public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew)
106  : this(initialCount, maximumCount, name, out createdNew, null)
107  {
108  }
109 
125  [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
126  public unsafe Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity)
127  {
128  if (initialCount < 0)
129  {
130  throw new ArgumentOutOfRangeException("initialCount", SR.GetString("ArgumentOutOfRange_NeedNonNegNumRequired"));
131  }
132  if (maximumCount < 1)
133  {
134  throw new ArgumentOutOfRangeException("maximumCount", SR.GetString("ArgumentOutOfRange_NeedNonNegNumRequired"));
135  }
136  if (initialCount > maximumCount)
137  {
138  throw new ArgumentException(SR.GetString("Argument_SemaphoreInitialMaximum"));
139  }
140  if (name != null && 260 < name.Length)
141  {
142  throw new ArgumentException(SR.GetString("Argument_WaitHandleNameTooLong"));
143  }
144  SafeWaitHandle safeWaitHandle;
145  if (semaphoreSecurity != null)
146  {
147  Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES sECURITY_ATTRIBUTES = null;
148  sECURITY_ATTRIBUTES = new Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES();
149  sECURITY_ATTRIBUTES.nLength = Marshal.SizeOf((object)sECURITY_ATTRIBUTES);
150  byte[] securityDescriptorBinaryForm = semaphoreSecurity.GetSecurityDescriptorBinaryForm();
151  byte[] array = securityDescriptorBinaryForm;
152  fixed (byte* value = array)
153  {
154  sECURITY_ATTRIBUTES.lpSecurityDescriptor = new SafeLocalMemHandle((IntPtr)(void*)value, ownsHandle: false);
155  safeWaitHandle = Microsoft.Win32.SafeNativeMethods.CreateSemaphore(sECURITY_ATTRIBUTES, initialCount, maximumCount, name);
156  }
157  }
158  else
159  {
160  safeWaitHandle = Microsoft.Win32.SafeNativeMethods.CreateSemaphore(null, initialCount, maximumCount, name);
161  }
162  int lastWin32Error = Marshal.GetLastWin32Error();
163  if (safeWaitHandle.IsInvalid)
164  {
165  if (name != null && name.Length != 0 && 6 == lastWin32Error)
166  {
167  throw new WaitHandleCannotBeOpenedException(SR.GetString("WaitHandleCannotBeOpenedException_InvalidHandle", name));
168  }
169  InternalResources.WinIOError();
170  }
171  createdNew = (lastWin32Error != 183);
172  base.SafeWaitHandle = safeWaitHandle;
173  }
174 
175  private Semaphore(SafeWaitHandle handle)
176  {
177  base.SafeWaitHandle = handle;
178  }
179 
191  [global::__DynamicallyInvokable]
192  [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
193  public static Semaphore OpenExisting(string name)
194  {
195  return OpenExisting(name, SemaphoreRights.Modify | SemaphoreRights.Synchronize);
196  }
197 
210  [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
211  public static Semaphore OpenExisting(string name, SemaphoreRights rights)
212  {
213  Semaphore result;
214  switch (OpenExistingWorker(name, rights, out result))
215  {
216  case OpenExistingResult.NameNotFound:
218  case OpenExistingResult.NameInvalid:
219  throw new WaitHandleCannotBeOpenedException(SR.GetString("WaitHandleCannotBeOpenedException_InvalidHandle", name));
220  case OpenExistingResult.PathNotFound:
221  InternalResources.WinIOError(3, string.Empty);
222  return result;
223  default:
224  return result;
225  }
226  }
227 
240  [global::__DynamicallyInvokable]
241  [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
242  public static bool TryOpenExisting(string name, out Semaphore result)
243  {
244  return OpenExistingWorker(name, SemaphoreRights.Modify | SemaphoreRights.Synchronize, out result) == OpenExistingResult.Success;
245  }
246 
260  [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
261  public static bool TryOpenExisting(string name, SemaphoreRights rights, out Semaphore result)
262  {
263  return OpenExistingWorker(name, rights, out result) == OpenExistingResult.Success;
264  }
265 
266  [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
267  private static OpenExistingResult OpenExistingWorker(string name, SemaphoreRights rights, out Semaphore result)
268  {
269  if (name == null)
270  {
271  throw new ArgumentNullException("name");
272  }
273  if (name.Length == 0)
274  {
275  throw new ArgumentException(SR.GetString("InvalidNullEmptyArgument", "name"), "name");
276  }
277  if (name != null && 260 < name.Length)
278  {
279  throw new ArgumentException(SR.GetString("Argument_WaitHandleNameTooLong"));
280  }
281  result = null;
282  SafeWaitHandle safeWaitHandle = Microsoft.Win32.SafeNativeMethods.OpenSemaphore((int)rights, inheritHandle: false, name);
283  if (safeWaitHandle.IsInvalid)
284  {
285  int lastWin32Error = Marshal.GetLastWin32Error();
286  if (2 == lastWin32Error || 123 == lastWin32Error)
287  {
288  return OpenExistingResult.NameNotFound;
289  }
290  if (3 == lastWin32Error)
291  {
292  return OpenExistingResult.PathNotFound;
293  }
294  if (name != null && name.Length != 0 && 6 == lastWin32Error)
295  {
296  return OpenExistingResult.NameInvalid;
297  }
298  InternalResources.WinIOError();
299  }
300  result = new Semaphore(safeWaitHandle);
301  return OpenExistingResult.Success;
302  }
303 
309  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
310  [PrePrepareMethod]
311  [global::__DynamicallyInvokable]
312  public int Release()
313  {
314  return Release(1);
315  }
316 
325  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
326  [global::__DynamicallyInvokable]
327  public int Release(int releaseCount)
328  {
329  if (releaseCount < 1)
330  {
331  throw new ArgumentOutOfRangeException("releaseCount", SR.GetString("ArgumentOutOfRange_NeedNonNegNumRequired"));
332  }
333  if (!Microsoft.Win32.SafeNativeMethods.ReleaseSemaphore(base.SafeWaitHandle, releaseCount, out int previousCount))
334  {
335  throw new SemaphoreFullException();
336  }
337  return previousCount;
338  }
339 
345  {
346  return new SemaphoreSecurity(base.SafeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
347  }
348 
355  public void SetAccessControl(SemaphoreSecurity semaphoreSecurity)
356  {
357  if (semaphoreSecurity == null)
358  {
359  throw new ArgumentNullException("semaphoreSecurity");
360  }
361  semaphoreSecurity.Persist(base.SafeWaitHandle);
362  }
363  }
364 }
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
Describes a set of security permissions applied to code. This class cannot be inherited.
static Semaphore OpenExisting(string name, SemaphoreRights rights)
Opens the specified named semaphore, if it already exists, with the desired security access.
Definition: Semaphore.cs:211
Encapsulates operating system–specific objects that wait for exclusive access to shared resources.
Definition: WaitHandle.cs:15
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.
Definition: WaitHandle.cs:86
Definition: __Canon.cs:3
void SetAccessControl(SemaphoreSecurity semaphoreSecurity)
Sets the access control security for a named system semaphore.
Definition: Semaphore.cs:355
The exception that is thrown when the value of an argument is outside the allowable range of values a...
static Semaphore OpenExisting(string name)
Opens the specified named semaphore, if it already exists.
Definition: Semaphore.cs:193
static int SizeOf(object structure)
Returns the unmanaged size of an object in bytes.
Definition: Marshal.cs:159
int Release(int releaseCount)
Exits the semaphore a specified number of times and returns the previous count.
Definition: Semaphore.cs:327
Semaphore(int initialCount, int maximumCount)
Initializes a new instance of the T:System.Threading.Semaphore class, specifying the initial number o...
Definition: Semaphore.cs:38
unsafe Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity)
Initializes a new instance of the T:System.Threading.Semaphore class, specifying the initial number o...
Definition: Semaphore.cs:126
Cer
Specifies a method's behavior when called within a constrained execution region.
Definition: Cer.cs:5
SecurityAction
Specifies the security actions that can be performed using declarative security.
static bool TryOpenExisting(string name, out Semaphore result)
Opens the specified named semaphore, if it already exists, and returns a value that indicates whether...
Definition: Semaphore.cs:242
SemaphoreRights
Specifies the access control rights that can be applied to named system semaphore objects.
Semaphore(int initialCount, int maximumCount, string name, out bool createdNew)
Initializes a new instance of the T:System.Threading.Semaphore class, specifying the initial number o...
Definition: Semaphore.cs:105
Semaphore(int initialCount, int maximumCount, string name)
Initializes a new instance of the T:System.Threading.Semaphore class, specifying the initial number o...
Definition: Semaphore.cs:58
A platform-specific type that is used to represent a pointer or a handle.
Definition: IntPtr.cs:14
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Definition: Marshal.cs:15
SemaphoreSecurity GetAccessControl()
Gets the access control security for a named system semaphore.
Definition: Semaphore.cs:344
The exception that is thrown when the Overload:System.Threading.Semaphore.Release method is called on...
Limits the number of threads that can access a resource or pool of resources concurrently.
Definition: Semaphore.cs:16
Represents the Windows access control security for a named semaphore. This class cannot be inherited.
int Release()
Exits the semaphore and returns the previous count.
Definition: Semaphore.cs:312
The exception that is thrown when one of the arguments provided to a method is not valid.
static bool TryOpenExisting(string name, SemaphoreRights rights, out Semaphore result)
Opens the specified named semaphore, if it already exists, with the desired security access,...
Definition: Semaphore.cs:261
Consistency
Specifies a reliability contract.
Definition: Consistency.cs:5
static int GetLastWin32Error()
Returns the error code returned by the last unmanaged function that was called using platform invoke ...
SecurityPermissionFlag
Specifies access flags for the security permission object.
AccessControlSections
Specifies which sections of a security descriptor to save or load.