</ItemGroup>
<ItemGroup>
<Compile Include="$(BclSourcesRoot)\System\Threading\SynchronizationContext.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Threading\EventWaitHandle.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\Interlocked.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\Monitor.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\Overlapped.cs" />
internal const int SYNCHRONIZE = 0x00100000;
internal const int MUTEX_MODIFY_STATE = 0x00000001;
internal const int SEMAPHORE_MODIFY_STATE = 0x00000002;
+ internal const int EVENT_MODIFY_STATE = 0x00000002;
}
}
--- /dev/null
+// 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;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Kernel32
+ {
+ internal const uint CREATE_EVENT_INITIAL_SET = 0x2;
+ internal const uint CREATE_EVENT_MANUAL_RESET = 0x1;
+
+ [DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
+ internal static extern bool SetEvent(SafeWaitHandle handle);
+
+ [DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
+ internal static extern bool ResetEvent(SafeWaitHandle handle);
+
+ [DllImport(Interop.Libraries.Kernel32, EntryPoint = "CreateEventExW", SetLastError = true, CharSet = CharSet.Unicode)]
+ internal static extern SafeWaitHandle CreateEventEx(IntPtr lpSecurityAttributes, string name, uint flags, uint desiredAccess);
+
+ [DllImport(Interop.Libraries.Kernel32, EntryPoint = "OpenEventW", SetLastError = true, CharSet = CharSet.Unicode)]
+ internal static extern SafeWaitHandle OpenEvent(uint desiredAccess, bool inheritHandle, string name);
+ }
+}
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\AutoResetEvent.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\DeferredDisposableLifetime.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\EventResetMode.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\EventWaitHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\ExecutionContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LazyInitializer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LazyThreadSafetyMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FormatMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.Mutex.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.Semaphore.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.EventWaitHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Win32Marshal.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Mutex.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Semaphore.Windows.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\EventWaitHandle.Windows.cs" />
</ItemGroup>
<ItemGroup Condition="$(TargetsUnix)">
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\Interop.Errors.cs" />
--- /dev/null
+// 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() => Set(_waitHandle);
+
+ internal bool Set(SafeWaitHandle handle)
+ {
+ bool res = Interop.Kernel32.SetEvent(_waitHandle);
+ if (!res)
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ return res;
+ }
+ }
+}
--- /dev/null
+// 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;
+
+namespace System.Threading
+{
+ public partial class EventWaitHandle : WaitHandle
+ {
+ public EventWaitHandle(bool initialState, EventResetMode mode) :
+ this(initialState, mode, null, out _)
+ {
+ }
+
+ public EventWaitHandle(bool initialState, EventResetMode mode, string name) :
+ this(initialState, mode, name, out _)
+ {
+ }
+
+ public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew)
+ {
+ if (mode != EventResetMode.AutoReset && mode != EventResetMode.ManualReset)
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(mode));
+
+ CreateEventCore(initialState, mode, name, out createdNew);
+ }
+
+ public static EventWaitHandle OpenExisting(string name)
+ {
+ EventWaitHandle result;
+ switch (OpenExistingWorker(name, out result))
+ {
+ case OpenExistingResult.NameNotFound:
+ throw new WaitHandleCannotBeOpenedException();
+ case OpenExistingResult.NameInvalid:
+ throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
+ case OpenExistingResult.PathNotFound:
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, name));
+ default:
+ return result;
+ }
+ }
+
+ public static bool TryOpenExisting(string name, out EventWaitHandle result)
+ {
+ return OpenExistingWorker(name, out result) == OpenExistingResult.Success;
+ }
+ }
+}
// Win32 ACL-related constants:
internal const int READ_CONTROL = 0x00020000;
internal const int SYNCHRONIZE = 0x00100000;
- internal const int MAXIMUM_ALLOWED = 0x02000000;
internal const int STANDARD_RIGHTS_READ = READ_CONTROL;
internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
- // STANDARD_RIGHTS_REQUIRED (0x000F0000L)
- // SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
-
- // SEMAPHORE and Event both use 0x0002
- // MUTEX uses 0x001 (MUTANT_QUERY_STATE)
-
- // Note that you may need to specify the SYNCHRONIZE bit as well
- // to be able to open a synchronization primitive.
- internal const int EVENT_MODIFY_STATE = 0x00000002;
- internal const int MUTEX_MODIFY_STATE = 0x00000001;
-
- // CreateEventEx: flags
- internal const uint CREATE_EVENT_MANUAL_RESET = 0x1;
- internal const uint CREATE_EVENT_INITIAL_SET = 0x2;
-
internal const int LMEM_FIXED = 0x0000;
internal const int LMEM_ZEROINIT = 0x0040;
internal const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);
internal static extern uint SysStringByteLen(IntPtr bstr);
#endif
-
- [DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
- internal static extern bool SetEvent(SafeWaitHandle handle);
-
- [DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
- internal static extern bool ResetEvent(SafeWaitHandle handle);
-
- [DllImport(Interop.Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
- internal static extern SafeWaitHandle CreateEventEx(SECURITY_ATTRIBUTES lpSecurityAttributes, string name, uint flags, uint desiredAccess);
-
- [DllImport(Interop.Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
- internal static extern SafeWaitHandle OpenEvent(uint desiredAccess, bool inheritHandle, string name);
-
[DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
internal static extern bool CloseHandle(IntPtr handle);
+++ /dev/null
-// 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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: Base class for representing Events
-**
-**
-=============================================================================*/
-
-
-namespace System.Security.AccessControl
-{
- internal class EventWaitHandleSecurity
- {
- }
- internal enum EventWaitHandleRights
- {
- }
-}
-
-namespace System.Threading
-{
- using System;
- using System.Threading;
- using System.Runtime.CompilerServices;
- using System.IO;
- using Microsoft.Win32;
- using Microsoft.Win32.SafeHandles;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Security.AccessControl;
-
- [ComVisibleAttribute(true)]
- public class EventWaitHandle : WaitHandle
- {
- private const uint AccessRights =
- (uint)Win32Native.MAXIMUM_ALLOWED | Win32Native.SYNCHRONIZE | Win32Native.EVENT_MODIFY_STATE;
-
- public EventWaitHandle(bool initialState, EventResetMode mode) : this(initialState, mode, null) { }
-
- public EventWaitHandle(bool initialState, EventResetMode mode, string name)
- {
-#if !PLATFORM_WINDOWS
- if (name != null)
- {
- throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
- }
-#endif
-
- uint eventFlags = initialState ? Win32Native.CREATE_EVENT_INITIAL_SET : 0;
- switch (mode)
- {
- case EventResetMode.ManualReset:
- eventFlags |= Win32Native.CREATE_EVENT_MANUAL_RESET;
- break;
-
- case EventResetMode.AutoReset:
- break;
-
- default:
- throw new ArgumentException(SR.Format(SR.Argument_InvalidFlag, name));
- };
-
- SafeWaitHandle _handle = Win32Native.CreateEventEx(null, name, eventFlags, AccessRights);
-
- if (_handle.IsInvalid)
- {
- int errorCode = Marshal.GetLastWin32Error();
-
- _handle.SetHandleAsInvalid();
- if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
- throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
-
- throw Win32Marshal.GetExceptionForWin32Error(errorCode, name);
- }
- SetHandleInternal(_handle);
- }
-
- public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew)
- : this(initialState, mode, name, out createdNew, null)
- {
- }
-
- internal unsafe EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity)
- {
-#if !PLATFORM_WINDOWS
- if (name != null)
- {
- throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
- }
-#endif
- Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
-
- uint eventFlags = initialState ? Win32Native.CREATE_EVENT_INITIAL_SET : 0;
- switch (mode)
- {
- case EventResetMode.ManualReset:
- eventFlags |= Win32Native.CREATE_EVENT_MANUAL_RESET;
- break;
-
- case EventResetMode.AutoReset:
- break;
-
- default:
- throw new ArgumentException(SR.Format(SR.Argument_InvalidFlag, name));
- };
-
- SafeWaitHandle _handle = Win32Native.CreateEventEx(secAttrs, name, eventFlags, AccessRights);
-
- int errorCode = Marshal.GetLastWin32Error();
- if (_handle.IsInvalid)
- {
- _handle.SetHandleAsInvalid();
- if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
- throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
-
- throw Win32Marshal.GetExceptionForWin32Error(errorCode, name);
- }
- createdNew = errorCode != Interop.Errors.ERROR_ALREADY_EXISTS;
- SetHandleInternal(_handle);
- }
-
- private EventWaitHandle(SafeWaitHandle handle)
- {
- SetHandleInternal(handle);
- }
-
- public static EventWaitHandle OpenExisting(string name)
- {
- return OpenExisting(name, (EventWaitHandleRights)0);
- }
-
- internal static EventWaitHandle OpenExisting(string name, EventWaitHandleRights rights)
- {
- EventWaitHandle result;
- switch (OpenExistingWorker(name, rights, out result))
- {
- case OpenExistingResult.NameNotFound:
- throw new WaitHandleCannotBeOpenedException();
-
- case OpenExistingResult.NameInvalid:
- throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
-
- case OpenExistingResult.PathNotFound:
- throw Win32Marshal.GetExceptionForWin32Error(Interop.Errors.ERROR_PATH_NOT_FOUND, "");
-
- default:
- return result;
- }
- }
-
- public static bool TryOpenExisting(string name, out EventWaitHandle result)
- {
- return OpenExistingWorker(name, (EventWaitHandleRights)0, out result) == OpenExistingResult.Success;
- }
-
- private static OpenExistingResult OpenExistingWorker(string name, EventWaitHandleRights rights, 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 = Win32Native.OpenEvent(AccessRights, false, name);
-
- if (myHandle.IsInvalid)
- {
- int errorCode = Marshal.GetLastWin32Error();
-
- if (Interop.Errors.ERROR_FILE_NOT_FOUND == errorCode || Interop.Errors.ERROR_INVALID_NAME == errorCode)
- return OpenExistingResult.NameNotFound;
- if (Interop.Errors.ERROR_PATH_NOT_FOUND == errorCode)
- return OpenExistingResult.PathNotFound;
- if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
- return OpenExistingResult.NameInvalid;
- //this is for passed through Win32Native Errors
- throw Win32Marshal.GetExceptionForWin32Error(errorCode, "");
- }
- result = new EventWaitHandle(myHandle);
- return OpenExistingResult.Success;
-#else
- throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
-#endif
- }
- public bool Reset()
- {
- bool res = Win32Native.ResetEvent(_waitHandle);
- if (!res)
- throw Win32Marshal.GetExceptionForLastWin32Error();
- return res;
- }
- public bool Set()
- {
- bool res = Win32Native.SetEvent(_waitHandle);
-
- if (!res)
- throw Win32Marshal.GetExceptionForLastWin32Error();
-
- return res;
- }
- }
-}
-
internal void SignalNoCallbacksRunning()
{
- Win32Native.SetEvent(m_notifyWhenNoCallbacksRunning.SafeWaitHandle);
+ Interop.Kernel32.SetEvent(m_notifyWhenNoCallbacksRunning.SafeWaitHandle);
}
internal void CallCallback()
}
}
- // Assembly-private version that doesn't do a security check. Reduces the
- // number of link-time security checks when reading & writing to a file,
- // and helps avoid a link time check while initializing security (If you
- // call a Serialization method that requires security before security
- // has started up, the link time check will start up security, run
- // serialization code for some security attribute stuff, call into
- // FileStream, which will then call Sethandle, which requires a link time
- // security check.). While security has fixed that problem, we still
- // don't need to do a linktime check here.
- internal void SetHandleInternal(SafeWaitHandle handle)
- {
- _waitHandle = handle;
- waitHandle = handle.DangerousGetHandle();
- }
-
public virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
{
if (millisecondsTimeout < -1)