diff options
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs')
-rw-r--r-- | src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs b/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs new file mode 100644 index 000000000..2da53b2b8 --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs @@ -0,0 +1,93 @@ +// 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 System; +using System.IO; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +namespace System.Threading +{ + public partial class EventWaitHandle + { + private const uint AccessRights = (uint)Interop.Kernel32.MAXIMUM_ALLOWED | Interop.Kernel32.SYNCHRONIZE | Interop.Kernel32.EVENT_MODIFY_STATE; + + private EventWaitHandle(SafeWaitHandle handle) + { + SafeWaitHandle = handle; + } + + private void CreateEventCore(bool initialState, EventResetMode mode, string name, out bool createdNew) + { +#if !PLATFORM_WINDOWS + if (name != null) + throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives); +#endif + uint eventFlags = initialState ? Interop.Kernel32.CREATE_EVENT_INITIAL_SET : 0; + if (mode == EventResetMode.ManualReset) + eventFlags |= (uint)Interop.Kernel32.CREATE_EVENT_MANUAL_RESET; + + SafeWaitHandle handle = Interop.Kernel32.CreateEventEx(IntPtr.Zero, name, eventFlags, AccessRights); + + int errorCode = Marshal.GetLastWin32Error(); + if (handle.IsInvalid) + { + handle.SetHandleAsInvalid(); + if (name != null && name.Length != 0 && errorCode == Interop.Errors.ERROR_INVALID_HANDLE) + throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name)); + + throw Win32Marshal.GetExceptionForWin32Error(errorCode, name); + } + createdNew = errorCode != Interop.Errors.ERROR_ALREADY_EXISTS; + SafeWaitHandle = handle; + } + + private static OpenExistingResult OpenExistingWorker(string name, out EventWaitHandle result) + { +#if PLATFORM_WINDOWS + if (name == null) + throw new ArgumentNullException(nameof(name)); + if (name.Length == 0) + throw new ArgumentException(SR.Argument_EmptyName, nameof(name)); + + result = null; + SafeWaitHandle myHandle = Interop.Kernel32.OpenEvent(AccessRights, false, name); + + if (myHandle.IsInvalid) + { + 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; + + throw Win32Marshal.GetExceptionForWin32Error(errorCode, name); + } + result = new EventWaitHandle(myHandle); + return OpenExistingResult.Success; +#else + throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives); +#endif + } + + public bool Reset() + { + bool res = Interop.Kernel32.ResetEvent(_waitHandle); + if (!res) + throw Win32Marshal.GetExceptionForLastWin32Error(); + return res; + } + + public bool Set() + { + bool res = Interop.Kernel32.SetEvent(_waitHandle); + if (!res) + throw Win32Marshal.GetExceptionForLastWin32Error(); + return res; + } + } +} |