Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs b/src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs
new file mode 100644
index 000000000..8a14f5ef3
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs
@@ -0,0 +1,88 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace System.Threading
+{
+ public sealed partial class Semaphore
+ {
+ private const uint AccessRights = (uint)Interop.Kernel32.MAXIMUM_ALLOWED | Interop.Kernel32.SYNCHRONIZE | Interop.Kernel32.SEMAPHORE_MODIFY_STATE;
+
+ private Semaphore(SafeWaitHandle handle)
+ {
+ SafeWaitHandle = handle;
+ }
+
+ private void CreateSemaphoreCore(int initialCount, int maximumCount, string name, out bool createdNew)
+ {
+ Debug.Assert(initialCount >= 0);
+ Debug.Assert(maximumCount >= 1);
+ Debug.Assert(initialCount <= maximumCount);
+
+#if !PLATFORM_WINDOWS
+ if (name != null)
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
+#endif
+ SafeWaitHandle myHandle = Interop.Kernel32.CreateSemaphoreEx(IntPtr.Zero, initialCount, maximumCount, name, 0, AccessRights);
+
+ int errorCode = Marshal.GetLastWin32Error();
+ if (myHandle.IsInvalid)
+ {
+ if (name != null && name.Length != 0 && errorCode == Interop.Errors.ERROR_INVALID_HANDLE)
+ throw new WaitHandleCannotBeOpenedException(
+ SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
+
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ }
+ createdNew = errorCode != Interop.Errors.ERROR_ALREADY_EXISTS;
+ this.SafeWaitHandle = myHandle;
+ }
+
+ private static OpenExistingResult OpenExistingWorker(string name, out Semaphore result)
+ {
+#if PLATFORM_WINDOWS
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (name.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
+
+ // Pass false to OpenSemaphore to prevent inheritedHandles
+ SafeWaitHandle myHandle = Interop.Kernel32.OpenSemaphore(AccessRights, false, name);
+
+ if (myHandle.IsInvalid)
+ {
+ result = null;
+ int errorCode = Marshal.GetLastWin32Error();
+
+ if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND || errorCode == Interop.Errors.ERROR_INVALID_NAME)
+ return OpenExistingResult.NameNotFound;
+ if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND)
+ return OpenExistingResult.PathNotFound;
+ if (name != null && name.Length != 0 && errorCode == Interop.Errors.ERROR_INVALID_HANDLE)
+ return OpenExistingResult.NameInvalid;
+ // this is for passed through NativeMethods Errors
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ }
+
+ result = new Semaphore(myHandle);
+ return OpenExistingResult.Success;
+#else
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
+#endif
+ }
+
+ private int ReleaseCore(int releaseCount)
+ {
+ int previousCount;
+ if (!Interop.Kernel32.ReleaseSemaphore(SafeWaitHandle, releaseCount, out previousCount))
+ throw new SemaphoreFullException();
+
+ return previousCount;
+ }
+ }
+}