using Microsoft.Win32.SafeHandles; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using Vanara.Extensions; using Vanara.InteropServices; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; namespace Vanara.PInvoke { public static partial class Kernel32 { /// public const int INIT_ONCE_CTX_RESERVED_BITS = 2; // PINIT_ONCE_FN PTIMERAPCROUTINE /// /// An application-defined callback function. Specify a pointer to this function when calling the InitOnceExecuteOnce function. The /// PINIT_ONCE_FN type defines a pointer to this callback function. /// /// A pointer to the one-time initialization structure. /// An optional parameter that was passed to the callback function. /// /// The data to be stored with the one-time initialization structure. If Context references a value, the low-order /// INIT_ONCE_CTX_RESERVED_BITS of the value must be zero. If Context points to a data structure, the data structure must be DWORD-aligned. /// /// /// If the function returns TRUE, the block is marked as initialized. /// /// If the function returns FALSE, the block is not marked as initialized and the call to InitOnceExecuteOnce fails. To communicate /// additional error information, call SetLastError before returning FALSE. /// /// [UnmanagedFunctionPointer(CallingConvention.Winapi)] [return: MarshalAs(UnmanagedType.Bool)] public delegate bool InitOnceCallback(ref INIT_ONCE InitOnce, IntPtr Parameter, out IntPtr Context); /// /// An application-defined timer completion routine. Specify this address when calling the SetWaitableTimer function. The /// PTIMERAPCROUTINE type defines a pointer to this callback function. /// /// /// The value passed to the function using the lpArgToCompletionRoutine parameter of the SetWaitableTimer function. /// /// /// The low-order portion of the UTC-based time at which the timer was signaled. This value corresponds to the dwLowDateTime member /// of the FILETIME structure. For more information about UTC-based time, see System Time. /// /// /// The high-order portion of the UTC-based time at which the timer was signaled. This value corresponds to the dwHighDateTime member /// of the FILETIME structure. /// [UnmanagedFunctionPointer(CallingConvention.Winapi)] public delegate void TimerAPCProc([In] IntPtr lpArgToCompletionRoutine, uint dwTimerLowValue, uint dwTimerHighValue); /// Used by . [Flags] public enum CONDITION_VARIABLE_FLAGS { /// The SRW lock is in exclusive mode. CONDITION_VARIABLE_INIT = 0, /// The SRW lock is in shared mode. CONDITION_VARIABLE_LOCKMODE_SHARED = 1, } /// Flags used by . [Flags] public enum CREATE_EVENT_FLAGS : uint { /// /// The event must be manually reset using the ResetEvent function. Any number of waiting threads, or threads that subsequently /// begin wait operations for the specified event object, can be released while the object's state is signaled.If this flag is /// not specified, the system automatically resets the event after releasing a single waiting thread. /// CREATE_EVENT_MANUAL_RESET = 0x00000001, /// The initial state of the event object is signaled; otherwise, it is nonsignaled. CREATE_EVENT_INITIAL_SET = 0x00000002, } /// Flags used by CreateMutexEx [Flags] public enum CREATE_MUTEX_FLAGS : uint { /// The object creator is the initial owner of the mutex. CREATE_MUTEX_INITIAL_OWNER = 0x00000001 } /// Used by CreateWaitableTimerEx [Flags] public enum CREATE_WAITABLE_TIMER_FLAG { /// The system automatically resets the timer after releasing a single waiting thread. CREATE_WAITABLE_TIMER_AUTOMATIC_RESET = 0x00000000, /// The timer must be manually reset. CREATE_WAITABLE_TIMER_MANUAL_RESET = 0x00000001, /// Creates a high resolution timer. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002, } /// Define the upper byte of the critical section SpinCount field. [Flags] public enum CRITICAL_SECTION_FLAGS : uint { /// The critical section is created without debug information. CRITICAL_SECTION_FLAG_NO_DEBUG_INFO = 0x01000000, /// CRITICAL_SECTION_FLAG_DYNAMIC_SPIN = 0x02000000, /// CRITICAL_SECTION_FLAG_STATIC_INIT = 0x04000000, /// CRITICAL_SECTION_FLAG_RESOURCE_TYPE = 0x08000000, /// CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO = 0x10000000, /// CRITICAL_SECTION_ALL_FLAG_BITS = 0xFF000000, } /// Used by REASON_CONTEXT. public enum DIAGNOSTIC_REASON : uint { /// /// The SimpleReasonString parameter contains a simple, non-localizable string that describes the reason for the power request. /// DIAGNOSTIC_REASON_SIMPLE_STRING = 0x00000001, /// The Detailed structure identifies a localizable string resource that describes the reason for the power request. DIAGNOSTIC_REASON_DETAILED_STRING = 0x00000002, /// Unspecified. DIAGNOSTIC_REASON_NOT_SPECIFIED = 0x80000000 } /// Used by REASON_CONTEXT. public enum DIAGNOSTIC_REASON_VERSION { /// The diagnostic reason version DIAGNOSTIC_REASON_VERSION = 0 } /// Flags for InitOnceBeginInitialize. [Flags] public enum INIT_ONCE_FLAGS : uint { /// /// This function call does not begin initialization. The return value indicates whether initialization has already completed. If /// the function returns TRUE, the lpContext parameter receives the data. /// INIT_ONCE_CHECK_ONLY = 0x00000001, /// /// Enables multiple initialization attempts to execute in parallel. If this flag is used, subsequent calls to this function will /// fail unless this flag is also specified. /// INIT_ONCE_ASYNC = 0x00000002, /// The initialize once initialize failed INIT_ONCE_INIT_FAILED = 0x00000004, } /// Flags that control the behavior of threads that enter this barrier. [Flags] public enum SYNC_BARRIER_FLAGS { /// /// Specifies that the thread entering the barrier should spin until the last thread enters the barrier, even if the spinning /// thread exceeds the barrier's maximum spin count. /// SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY = 0x01, /// Specifies that the thread entering the barrier should block immediately until the last thread enters the barrier. SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY = 0x02, /// /// Specifies that the function can skip the work required to ensure that it is safe to delete the barrier, which can improve /// performance. All threads that enter this barrier must specify the flag; otherwise, the flag is ignored. This flag should be /// used only if the barrier will never be deleted. /// SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE = 0x04, } /// Synchronization object access flags. [PInvokeData("synchapi.h")] [Flags] public enum SynchronizationObjectAccess : uint { /// Modify state access, which is required for the SetEvent, ResetEvent and PulseEvent functions. EVENT_MODIFY_STATE = 0x0002, /// /// All possible access rights for an event object. Use this right only if your application requires access beyond that granted /// by the standard access rights and EVENT_MODIFY_STATE. Using this access right increases the possibility that your application /// must be run by an Administrator. /// EVENT_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | ACCESS_MASK.SYNCHRONIZE | 0x3, /// Reserved for future use. MUTEX_QUERY_STATE = 0x0001, /// /// All possible access rights for a mutex object. Use this right only if your application requires access beyond that granted by /// the standard access rights. Using this access right increases the possibility that your application must be run by an Administrator. /// MUTEX_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | ACCESS_MASK.SYNCHRONIZE | MUTEX_QUERY_STATE, /// Modify state access, which is required for the ReleaseSemaphore function. SEMAPHORE_MODIFY_STATE = 0x0002, /// /// All possible access rights for a semaphore object. Use this right only if your application requires access beyond that /// granted by the standard access rights and SEMAPHORE_MODIFY_STATE. Using this access right increases the possibility that your /// application must be run by an Administrator. /// SEMAPHORE_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | ACCESS_MASK.SYNCHRONIZE | 0x3, /// Reserved for future use. TIMER_QUERY_STATE = 0x0001, /// Modify state access, which is required for the SetWaitableTimer and CancelWaitableTimer functions. TIMER_MODIFY_STATE = 0x0002, /// /// All possible access rights for a waitable timer object. Use this right only if your application requires access beyond that /// granted by the standard access rights and TIMER_MODIFY_STATE. Using this access right increases the possibility that your /// application must be run by an Administrator. /// TIMER_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | ACCESS_MASK.SYNCHRONIZE | TIMER_QUERY_STATE | TIMER_MODIFY_STATE, } /// Values returned by . public enum WAIT_STATUS : uint { /// /// The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning /// thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.If the /// mutex was protecting persistent state information, you should check it for consistency. /// WAIT_ABANDONED = 0x00000080, /// The wait was ended by one or more user-mode asynchronous procedure calls (APC) queued to the thread. WAIT_IO_COMPLETION = 0x000000C0, /// The state of the specified object is signaled. WAIT_OBJECT_0 = 0x00000000, /// The time-out interval elapsed, and the object's state is nonsignaled. WAIT_TIMEOUT = 0x00000102, /// The function has failed. To get extended error information, call GetLastError. WAIT_FAILED = 0xFFFFFFFF, } /// Acquires a slim reader/writer (SRW) lock in exclusive mode. /// A pointer to the SRW lock. /// This function does not return a value. // VOID WINAPI AcquireSRWLockExclusive( _Inout_ PSRWLOCK SRWLock); https://msdn.microsoft.com/en-us/library/windows/desktop/ms681930(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms681930")] public static extern void AcquireSRWLockExclusive(ref SRWLOCK SRWLock); /// Acquires a slim reader/writer (SRW) lock in shared mode. /// A pointer to the SRW lock. /// This function does not return a value. // VOID WINAPI AcquireSRWLockShared( _Inout_ PSRWLOCK SRWLock); https://msdn.microsoft.com/en-us/library/windows/desktop/ms681934(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms681934")] public static extern void AcquireSRWLockShared(ref SRWLOCK SRWLock); /// Sets the specified waitable timer to the inactive state. /// /// A handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle. The handle /// must have the TIMER_MODIFY_STATE access right. For more information, see Synchronization Object Security and Access Rights. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI CancelWaitableTimer( _In_ HANDLE hTimer); https://msdn.microsoft.com/en-us/library/windows/desktop/ms681985(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms681985")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CancelWaitableTimer([In] SafeWaitableTimerHandle hTimer); /// /// Creates or opens a named or unnamed event object. /// To specify an access mask for the object, use the CreateEventEx function. /// /// /// /// A pointer to a SECURITY_ATTRIBUTES structure. If this parameter is NULL, the handle cannot be inherited by child processes. /// /// /// The lpSecurityDescriptor member of the structure specifies a security descriptor for the new event. If lpEventAttributes /// is NULL, the event gets a default security descriptor. The ACLs in the default security descriptor for an event come from /// the primary or impersonation token of the creator. /// /// /// /// If this parameter is TRUE, the function creates a manual-reset event object, which requires the use of the /// ResetEvent function to set the event state to nonsignaled. If this parameter is FALSE, the function creates an /// auto-reset event object, and system automatically resets the event state to nonsignaled after a single waiting thread has been released. /// /// /// If this parameter is TRUE, the initial state of the event object is signaled; otherwise, it is nonsignaled. /// /// /// The name of the event object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. /// /// If lpName matches the name of an existing named event object, this function requests the EVENT_ALL_ACCESS access right. In /// this case, the bManualReset and bInitialState parameters are ignored because they have already been set by the creating process. /// If the lpEventAttributes parameter is not NULL, it determines whether the handle can be inherited, but its /// security-descriptor member is ignored. /// /// If lpName is NULL, the event object is created without a name. /// /// If lpName matches the name of another kind of object in the same namespace (such as an existing semaphore, mutex, waitable timer, /// job, or file-mapping object), the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This /// occurs because these objects share the same namespace. /// /// /// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The /// remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object /// Namespaces. Fast user switching is implemented using Terminal Services sessions. Kernel object names must follow the guidelines /// outlined for Terminal Services so that applications can support multiple users. /// /// The object can be created in a private namespace. For more information, see Object Namespaces. /// /// /// /// If the function succeeds, the return value is a handle to the event object. If the named event object existed before the function /// call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. /// /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI CreateEvent( _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, _In_ BOOL bManualReset, _In_ BOOL bInitialState, // _In_opt_ LPCTSTR lpName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682396")] public static extern SafeEventHandle CreateEvent([In, Optional] SECURITY_ATTRIBUTES lpEventAttributes, [MarshalAs(UnmanagedType.Bool)] bool bManualReset, [MarshalAs(UnmanagedType.Bool)] bool bInitialState, [In, Optional] string lpName); /// Creates or opens a named or unnamed event object and returns a handle to the object. /// /// /// A pointer to a SECURITY_ATTRIBUTES structure. If lpEventAttributes is NULL, the event handle cannot be inherited by /// child processes. /// /// /// The lpSecurityDescriptor member of the structure specifies a security descriptor for the new event. If lpEventAttributes /// is NULL, the event gets a default security descriptor. The ACLs in the default security descriptor for an event come from /// the primary or impersonation token of the creator. /// /// /// /// The name of the event object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. /// If lpName is NULL, the event object is created without a name. /// /// If lpName matches the name of another kind of object in the same namespace (such as an existing semaphore, mutex, waitable timer, /// job, or file-mapping object), the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This /// occurs because these objects share the same namespace. /// /// /// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The /// remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object /// Namespaces. Fast user switching is implemented using Terminal Services sessions. Kernel object names must follow the guidelines /// outlined for Terminal Services so that applications can support multiple users. /// /// The object can be created in a private namespace. For more information, see Object Namespaces. /// /// /// This parameter can be one or more of the following values. /// /// /// /// Value /// Meaning /// /// /// CREATE_EVENT_INITIAL_SET = 0x00000002 /// The initial state of the event object is signaled; otherwise, it is nonsignaled. /// /// /// CREATE_EVENT_MANUAL_RESET = 0x00000001 /// /// The event must be manually reset using the ResetEvent function. Any number of waiting threads, or threads that subsequently begin /// wait operations for the specified event object, can be released while the object's state is signaled.If this flag is not /// specified, the system automatically resets the event after releasing a single waiting thread. /// /// /// /// /// /// /// The access mask for the event object. For a list of access rights, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is a handle to the event object. If the named event object existed before the function /// call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. /// /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI CreateEventEx( _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, _In_opt_ LPCTSTR lpName, _In_ DWORD dwFlags, _In_ // DWORD dwDesiredAccess); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682400(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682400")] public static extern SafeEventHandle CreateEventEx([In, Optional] SECURITY_ATTRIBUTES lpEventAttributes, [In, Optional] string lpName, CREATE_EVENT_FLAGS dwFlags, ACCESS_MASK dwDesiredAccess); /// /// Creates or opens a named or unnamed mutex object. /// To specify an access mask for the object, use the CreateMutexEx function. /// /// /// /// A pointer to a SECURITY_ATTRIBUTES structure. If this parameter is NULL, the handle cannot be inherited by child processes. /// /// /// The lpSecurityDescriptor member of the structure specifies a security descriptor for the new mutex. If lpMutexAttributes /// is NULL, the mutex gets a default security descriptor. The ACLs in the default security descriptor for a mutex come from /// the primary or impersonation token of the creator. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// If this value is TRUE and the caller created the mutex, the calling thread obtains initial ownership of the mutex object. /// Otherwise, the calling thread does not obtain ownership of the mutex. To determine if the caller created the mutex, see the /// Return Values section. /// /// /// The name of the mutex object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. /// /// If lpName matches the name of an existing named mutex object, this function requests the MUTEX_ALL_ACCESS access right. In /// this case, the bInitialOwner parameter is ignored because it has already been set by the creating process. If the /// lpMutexAttributes parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor /// member is ignored. /// /// If lpName is NULL, the mutex object is created without a name. /// /// If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and /// the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace. /// /// /// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The /// remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object /// Namespaces. Fast user switching is implemented using Terminal Services sessions. Kernel object names must follow the guidelines /// outlined for Terminal Services so that applications can support multiple users. /// /// The object can be created in a private namespace. For more information, see Object Namespaces. /// /// /// If the function succeeds, the return value is a handle to the newly created mutex object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// /// If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing /// object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted /// ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the /// caller should use the OpenMutex function. /// /// // HANDLE WINAPI CreateMutex( _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, _In_ BOOL bInitialOwner, _In_opt_ LPCTSTR lpName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682411(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682411")] public static extern SafeMutexHandle CreateMutex([In, Optional] SECURITY_ATTRIBUTES lpMutexAttributes, [MarshalAs(UnmanagedType.Bool)] bool bInitialOwner, [In, Optional] string lpName); /// Creates or opens a named or unnamed mutex object and returns a handle to the object. /// /// /// A pointer to a SECURITY_ATTRIBUTES structure. If this parameter is NULL, the mutex handle cannot be inherited by /// child processes. /// /// /// The lpSecurityDescriptor member of the structure specifies a security descriptor for the new mutex. If lpMutexAttributes /// is NULL, the mutex gets a default security descriptor. The ACLs in the default security descriptor for a mutex come from /// the primary or impersonation token of the creator. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// The name of the mutex object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. /// If lpName is NULL, the mutex object is created without a name. /// /// If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and /// the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace. /// /// /// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The /// remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object /// Namespaces. Fast user switching is implemented using Terminal Services sessions. Kernel object names must follow the guidelines /// outlined for Terminal Services so that applications can support multiple users. /// /// The object can be created in a private namespace. For more information, see Object Namespaces. /// /// /// This parameter can be 0 or the following value. /// /// /// /// Value /// Meaning /// /// /// CREATE_MUTEX_INITIAL_OWNER = 0x00000001 /// The object creator is the initial owner of the mutex. /// /// /// /// /// /// The access mask for the mutex object. For a list of access rights, see Synchronization Object Security and Access Rights. /// /// /// If the function succeeds, the return value is a handle to the newly created mutex object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// /// If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing /// object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted /// ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the /// caller should use the OpenMutex function. /// /// // HANDLE WINAPI CreateMutexEx( _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, _In_opt_ LPCTSTR lpName, _In_ DWORD dwFlags, _In_ // DWORD dwDesiredAccess); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682418(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682418")] public static extern SafeMutexHandle CreateMutexEx([In, Optional] SECURITY_ATTRIBUTES lpMutexAttributes, [In, Optional] string lpName, CREATE_MUTEX_FLAGS dwFlags, ACCESS_MASK dwDesiredAccess); /// /// Creates or opens a named or unnamed semaphore object. /// To specify an access mask for the object, use the CreateSemaphoreEx function. /// /// /// /// A pointer to a SECURITY_ATTRIBUTES structure. If this parameter is NULL, the handle cannot be inherited by child processes. /// /// /// The lpSecurityDescriptor member of the structure specifies a security descriptor for the new semaphore. If this parameter /// is NULL, the semaphore gets a default security descriptor. The ACLs in the default security descriptor for a semaphore /// come from the primary or impersonation token of the creator. /// /// /// /// The initial count for the semaphore object. This value must be greater than or equal to zero and less than or equal to /// lMaximumCount. The state of a semaphore is signaled when its count is greater than zero and nonsignaled when it is zero. The /// count is decreased by one whenever a wait function releases a thread that was waiting for the semaphore. The count is increased /// by a specified amount by calling the ReleaseSemaphore function. /// /// The maximum count for the semaphore object. This value must be greater than zero. /// /// The name of the semaphore object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. /// /// If lpName matches the name of an existing named semaphore object, this function requests the SEMAPHORE_ALL_ACCESS access /// right. In this case, the lInitialCount and lMaximumCount parameters are ignored because they have already been set by the /// creating process. If the lpSemaphoreAttributes parameter is not NULL, it determines whether the handle can be inherited, /// but its security-descriptor member is ignored. /// /// If lpName is NULL, the semaphore object is created without a name. /// /// If lpName matches the name of an existing event, mutex, waitable timer, job, or file-mapping object, the function fails and the /// GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace. /// /// /// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The /// remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object /// Namespaces. Fast user switching is implemented using Terminal Services sessions. Kernel object names must follow the guidelines /// outlined for Terminal Services so that applications can support multiple users. /// /// The object can be created in a private namespace. For more information, see Object Namespaces. /// /// /// /// If the function succeeds, the return value is a handle to the semaphore object. If the named semaphore object existed before the /// function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. /// /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI CreateSemaphore( _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, _In_ LONG lInitialCount, _In_ LONG // lMaximumCount, _In_opt_ LPCTSTR lpName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682438(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682438")] public static extern SafeSemaphoreHandle CreateSemaphore([In, Optional] SECURITY_ATTRIBUTES lpSemaphoreAttributes, int lInitialCount, int lMaximumCount, [In, Optional] string lpName); /// Creates or opens a named or unnamed semaphore object and returns a handle to the object. /// /// /// A pointer to a SECURITY_ATTRIBUTES structure. If this parameter is NULL, the semaphore handle cannot be inherited /// by child processes. /// /// /// The lpSecurityDescriptor member of the structure specifies a security descriptor for the new semaphore. If this parameter /// is NULL, the semaphore gets a default security descriptor. The ACLs in the default security descriptor for a semaphore /// come from the primary or impersonation token of the creator. /// /// /// /// The initial count for the semaphore object. This value must be greater than or equal to zero and less than or equal to /// lMaximumCount. The state of a semaphore is signaled when its count is greater than zero and nonsignaled when it is zero. The /// count is decreased by one whenever a wait function releases a thread that was waiting for the semaphore. The count is increased /// by a specified amount by calling the ReleaseSemaphore function. /// /// The maximum count for the semaphore object. This value must be greater than zero. /// /// /// A pointer to a null-terminated string specifying the name of the semaphore object. The name is limited to MAX_PATH /// characters. Name comparison is case sensitive. /// /// /// If lpName matches the name of an existing named semaphore object, the lInitialCount and lMaximumCount parameters are ignored /// because they have already been set by the creating process. If the lpSemaphoreAttributes parameter is not NULL, it /// determines whether the handle can be inherited. /// /// If lpName is NULL, the semaphore object is created without a name. /// /// If lpName matches the name of an existing event, mutex, waitable timer, job, or file-mapping object, the function fails and the /// GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace. /// /// /// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The /// remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object /// Namespaces. Fast user switching is implemented using Terminal Services sessions. Kernel object names must follow the guidelines /// outlined for Terminal Services so that applications can support multiple users. /// /// The object can be created in a private namespace. For more information, see Object Namespaces. /// /// This parameter is reserved and must be 0. /// /// The access mask for the semaphore object. For a list of access rights, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is a handle to the semaphore object. If the named semaphore object existed before the /// function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. /// /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI CreateSemaphoreEx( _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, _In_ LONG lInitialCount, _In_ LONG // lMaximumCount, _In_opt_ LPCTSTR lpName, _Reserved_ DWORD dwFlags, _In_ DWORD dwDesiredAccess); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682446(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682446")] public static extern SafeSemaphoreHandle CreateSemaphoreEx([In, Optional] SECURITY_ATTRIBUTES lpSemaphoreAttributes, int lInitialCount, int lMaximumCount, [In, Optional] string lpName, [Optional] uint dwFlags, ACCESS_MASK dwDesiredAccess); /// /// Creates or opens a waitable timer object. /// To specify an access mask for the object, use the CreateWaitableTimerEx function. /// /// /// /// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new timer object and determines /// whether child processes can inherit the returned handle. /// /// /// If lpTimerAttributes is NULL, the timer object gets a default security descriptor and the handle cannot be inherited. The /// ACLs in the default security descriptor for a timer come from the primary or impersonation token of the creator. /// /// /// /// If this parameter is TRUE, the timer is a manual-reset notification timer. Otherwise, the timer is a synchronization timer. /// /// /// The name of the timer object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. /// If lpTimerName is NULL, the timer object is created without a name. /// /// If lpTimerName matches the name of an existing event, semaphore, mutex, job, or file-mapping object, the function fails and /// GetLastError returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace. /// /// /// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The /// remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object /// Namespaces. Fast user switching is implemented using Terminal Services sessions. Kernel object names must follow the guidelines /// outlined for Terminal Services so that applications can support multiple users. /// /// The object can be created in a private namespace. For more information, see Object Namespaces. /// /// /// /// If the function succeeds, the return value is a handle to the timer object. If the named timer object exists before the function /// call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. /// /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI CreateWaitableTimer( _In_opt_ LPSECURITY_ATTRIBUTES lpTimerAttributes, _In_ BOOL bManualReset, _In_opt_ LPCTSTR // lpTimerName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682492(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682492")] public static extern SafeWaitableTimerHandle CreateWaitableTimer([In, Optional] SECURITY_ATTRIBUTES lpTimerAttributes, [MarshalAs(UnmanagedType.Bool)] bool bManualReset, [In, Optional] string lpTimerName); /// Creates or opens a waitable timer object and returns a handle to the object. /// /// /// A pointer to a SECURITY_ATTRIBUTES structure. If this parameter is NULL, the timer handle cannot be inherited by /// child processes. /// /// /// If lpTimerAttributes is NULL, the timer object gets a default security descriptor and the handle cannot be inherited. The /// ACLs in the default security descriptor for a timer come from the primary or impersonation token of the creator. /// /// /// /// The name of the timer object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. /// If lpTimerName is NULL, the timer object is created without a name. /// /// If lpTimerName matches the name of an existing event, semaphore, mutex, job, or file-mapping object, the function fails and /// GetLastError returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace. /// /// /// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The /// remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object /// Namespaces. Fast user switching is implemented using Terminal Services sessions. Kernel object names must follow the guidelines /// outlined for Terminal Services so that applications can support multiple users. /// /// The object can be created in a private namespace. For more information, see Object Namespaces. /// /// /// This parameter can be 0 or the following value. /// /// /// /// Value /// Meaning /// /// /// CREATE_WAITABLE_TIMER_MANUAL_RESET0x00000001 /// /// The timer must be manually reset. Otherwise, the system automatically resets the timer after releasing a single waiting thread. /// /// /// /// /// /// /// The access mask for the timer object. For a list of access rights, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is a handle to the timer object. If the named timer object exists before the function /// call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. /// /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI CreateWaitableTimerEx( _In_opt_ LPSECURITY_ATTRIBUTES lpTimerAttributes, _In_opt_ LPCTSTR lpTimerName, _In_ DWORD // dwFlags, _In_ DWORD dwDesiredAccess); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682494(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682494")] public static extern SafeWaitableTimerHandle CreateWaitableTimerEx([In, Optional] SECURITY_ATTRIBUTES lpTimerAttributes, [In, Optional] string lpTimerName, CREATE_WAITABLE_TIMER_FLAG dwFlags, ACCESS_MASK dwDesiredAccess); /// Releases all resources used by an unowned critical section object. /// /// A pointer to the critical section object. The object must have been previously initialized with the /// InitializeCriticalSection function. /// /// This function does not return a value. // void WINAPI DeleteCriticalSection( _Inout_ LPCRITICAL_SECTION lpCriticalSection); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682552(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms682552")] public static extern void DeleteCriticalSection(ref CRITICAL_SECTION lpCriticalSection); /// Deletes a synchronization barrier. /// A pointer to the synchronization barrier to delete. /// The DeleteSynchronizationBarrier function always returns TRUE. // BOOL WINAPI DeleteSynchronizationBarrier( _Inout_ LPSYNCHRONIZATION_BARRIER lpBarrier); https://msdn.microsoft.com/en-us/library/windows/desktop/hh706887(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("SynchAPI.h", MSDNShortId = "hh706887")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DeleteSynchronizationBarrier(ref SYNCHRONIZATION_BARRIER lpBarrier); /// Deletes a timer queue. Any pending timers in the queue are canceled and deleted. /// A handle to the timer queue. This handle is returned by the CreateTimerQueue function. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI DeleteTimerQueue( _In_ HANDLE TimerQueue); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682565(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms682565")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DeleteTimerQueue([In] IntPtr TimerQueue); /// /// Waits for ownership of the specified critical section object. The function returns when the calling thread is granted ownership. /// /// A pointer to the critical section object. /// /// This function does not return a value. /// /// This function can raise EXCEPTION_POSSIBLE_DEADLOCK if a wait operation on the critical section times out. The timeout /// interval is specified by the following registry value: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session /// Manager\ CriticalSectionTimeout. Do not handle a possible deadlock exception; instead, debug the application. /// /// // void WINAPI EnterCriticalSection( _Inout_ LPCRITICAL_SECTION lpCriticalSection); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682608(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms682608")] public static extern void EnterCriticalSection(ref CRITICAL_SECTION lpCriticalSection); /// /// Causes the calling thread to wait at a synchronization barrier until the maximum number of threads have entered the barrier. /// /// /// A pointer to an initialized synchronization barrier. Use the InitializeSynchronizationBarrier function to initialize the /// barrier. SYNCHRONIZATION_BARRIER is an opaque structure that should not be modified by the application. /// /// /// /// Flags that control the behavior of threads that enter this barrier. This parameter can be one or more of the following values. /// /// /// /// /// Value /// Meaning /// /// /// SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY /// /// Specifies that the thread entering the barrier should block immediately until the last thread enters the barrier. For more /// information, see Remarks. /// /// /// /// SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY /// /// Specifies that the thread entering the barrier should spin until the last thread enters the barrier, even if the spinning thread /// exceeds the barrier's maximum spin count. For more information, see Remarks. /// /// /// /// SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE /// /// Specifies that the function can skip the work required to ensure that it is safe to delete the barrier, which can improve /// performance. All threads that enter this barrier must specify the flag; otherwise, the flag is ignored. This flag should be used /// only if the barrier will never be deleted. /// /// /// /// /// /// /// TRUE for the last thread to signal the barrier. Threads that signal the barrier before the last thread signals it receive /// a return value of FALSE. /// // BOOL WINAPI EnterSynchronizationBarrier( _Inout_ LPSYNCHRONIZATION_BARRIER lpBarrier, _In_ DWORD dwFlags); https://msdn.microsoft.com/en-us/library/windows/desktop/hh706889(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("Synchapi.h", MSDNShortId = "hh706889")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnterSynchronizationBarrier(ref SYNCHRONIZATION_BARRIER lpBarrier, SYNC_BARRIER_FLAGS dwFlags); /// Initializes a condition variable. /// A pointer to the condition variable. /// This function does not return a value. // VOID WINAPI InitializeConditionVariable( _Out_ PCONDITION_VARIABLE ConditionVariable); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683469(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms683469")] public static extern void InitializeConditionVariable(out CONDITION_VARIABLE ConditionVariable); /// Initializes a critical section object. /// A pointer to the critical section object. /// /// This function does not return a value. /// /// Windows Server 2003 and Windows XP: In low memory situations, InitializeCriticalSection can raise a /// STATUS_NO_MEMORY exception. Starting with Windows Vista, this exception was eliminated and /// InitializeCriticalSection always succeeds, even in low memory situations. /// /// // void WINAPI InitializeCriticalSection( _Out_ LPCRITICAL_SECTION lpCriticalSection); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683472(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms683472")] public static extern void InitializeCriticalSection(out CRITICAL_SECTION lpCriticalSection); /// /// Initializes a critical section object and sets the spin count for the critical section. When a thread tries to acquire a critical /// section that is locked, the thread spins: it enters a loop which iterates spin count times, checking to see if the lock is /// released. If the lock is not released before the loop finishes, the thread goes to sleep to wait for the lock to be released. /// /// A pointer to the critical section object. /// /// The spin count for the critical section object. On single-processor systems, the spin count is ignored and the critical section /// spin count is set to 0 (zero). On multiprocessor systems, if the critical section is unavailable, the calling thread spins /// dwSpinCount times before performing a wait operation on a semaphore associated with the critical section. If the critical section /// becomes free during the spin operation, the calling thread avoids the wait operation. /// /// /// This function always succeeds and returns a nonzero value. /// /// Windows Server 2003 and Windows XP: If the function succeeds, the return value is nonzero. If the function fails, the /// return value is zero (0). To get extended error information, call GetLastError. Starting with Windows Vista, the /// InitializeCriticalSectionAndSpinCount function always succeeds, even in low memory situations. /// /// // BOOL WINAPI InitializeCriticalSectionAndSpinCount( _Out_ LPCRITICAL_SECTION lpCriticalSection, _In_ DWORD dwSpinCount); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683476(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms683476")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitializeCriticalSectionAndSpinCount(out CRITICAL_SECTION lpCriticalSection, uint dwSpinCount); /// Initializes a critical section object with a spin count and optional flags. /// A pointer to the critical section object. /// /// The spin count for the critical section object. On single-processor systems, the spin count is ignored and the critical section /// spin count is set to 0 (zero). On multiprocessor systems, if the critical section is unavailable, the calling thread spin /// dwSpinCount times before performing a wait operation on a semaphore associated with the critical section. If the critical section /// becomes free during the spin operation, the calling thread avoids the wait operation. /// /// /// This parameter can be 0 or the following value. /// /// /// Value /// Meaning /// /// /// CRITICAL_SECTION_NO_DEBUG_INFO /// The critical section is created without debug information. /// /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero (0). To get extended error information, call GetLastError. /// /// /// /// The threads of a single process can use a critical section object for mutual-exclusion synchronization. There is no guarantee /// about the order that threads obtain ownership of the critical section, however, the system is fair to all threads. /// /// /// The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable /// of type CRITICAL_SECTION. Before using a critical section, some thread of the process must initialize the object. You can /// subsequently modify the spin count by calling the SetCriticalSectionSpinCount function. /// /// /// After a critical section object is initialized, the threads of the process can specify the object in the EnterCriticalSection, /// TryEnterCriticalSection, or LeaveCriticalSection function to provide mutually exclusive access to a shared resource. For similar /// synchronization between the threads of different processes, use a mutex object. /// /// /// A critical section object cannot be moved or copied. The process must also not modify the object, but must treat it as logically /// opaque. Use only the critical section functions to manage critical section objects. When you have finished using the critical /// section, call the DeleteCriticalSection function. /// /// /// A critical section object must be deleted before it can be reinitialized. Initializing a critical section that is already /// initialized results in undefined behavior. /// /// /// The spin count is useful for critical sections of short duration that can experience high levels of contention. Consider a /// worst-case scenario, in which an application on an SMP system has two or three threads constantly allocating and releasing memory /// from the heap. The application serializes the heap with a critical section. In the worst-case scenario, contention for the /// critical section is constant, and each thread makes an processing-intensive call to the WaitForSingleObject function. However, if /// the spin count is set properly, the calling thread does not immediately call WaitForSingleObject when contention occurs. /// Instead, the calling thread can acquire ownership of the critical section if it is released during the spin operation. /// /// /// You can improve performance significantly by choosing a small spin count for a critical section of short duration. The heap /// manager uses a spin count of roughly 4000 for its per-heap critical sections. This gives great performance and scalability in /// almost all worst-case scenarios. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializecriticalsectionex // BOOL InitializeCriticalSectionEx( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags ); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("synchapi.h", MSDNShortId = "da84b187-0eb7-4363-8e68-8a525586d7d9")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitializeCriticalSectionEx(out CRITICAL_SECTION lpCriticalSection, uint dwSpinCount, CRITICAL_SECTION_FLAGS Flags); /// Initialize a slim reader/writer (SRW) lock. /// A pointer to the SRW lock. /// This function does not return a value. // VOID WINAPI InitializeSRWLock( _Out_ PSRWLOCK SRWLock); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683483(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms683483")] public static extern void InitializeSRWLock(out SRWLOCK SRWLock); /// Initializes a new synchronization barrier. /// /// A pointer to the SYNCHRONIZATION_BARRIER structure to initialize. This is an opaque structure that should not be modified /// by applications. /// /// /// The maximum number of threads that can enter this barrier. After the maximum number of threads have entered the barrier, all /// threads continue. /// /// /// The number of times an individual thread should spin while waiting for other threads to arrive at the barrier. If this parameter /// is -1, the thread spins 2000 times. If the thread exceeds lSpinCount, the thread blocks unless it called /// EnterSynchronizationBarrier with SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY. /// /// /// TRUE if the barrier was successfully initialized. If the barrier was not successfully initialized, this function returns /// FALSE. Use GetLastError to get extended error information. /// // BOOL WINAPI InitializeSynchronizationBarrier( _Out_ LPSYNCHRONIZATION_BARRIER lpBarrier, _In_ LONG lTotalThreads, _In_ LONG // lSpinCount); https://msdn.microsoft.com/en-us/library/windows/desktop/hh706890(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("SynchAPI.h", MSDNShortId = "hh706890")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitializeSynchronizationBarrier(out SYNCHRONIZATION_BARRIER lpBarrier, int lTotalThreads, int lSpinCount); /// Begins one-time initialization. /// A pointer to the one-time initialization structure. /// /// This parameter can be one or more of the following flags. /// /// /// /// Value /// Meaning /// /// /// INIT_ONCE_ASYNC = 0x00000002UL /// /// Enables multiple initialization attempts to execute in parallel. If this flag is used, subsequent calls to this function will /// fail unless this flag is also specified. /// /// /// /// INIT_ONCE_CHECK_ONLY = 0x00000001UL /// /// This function call does not begin initialization. The return value indicates whether initialization has already completed. If the /// function returns TRUE, the lpContext parameter receives the data. /// /// /// /// /// /// /// If the function succeeds, this parameter indicates the current initialization status. /// /// If this parameter is TRUE and dwFlags contains INIT_ONCE_CHECK_ONLY, the initialization is pending and the context /// data is invalid. /// /// /// If this parameter is FALSE, initialization has already completed and the caller can retrieve the context data from the /// lpContext parameter. /// /// /// If this parameter is TRUE and dwFlags does not contain INIT_ONCE_CHECK_ONLY, initialization has been started and /// the caller can perform the initialization tasks. /// /// /// /// An optional parameter that receives the data stored with the one-time initialization structure upon success. The low-order /// INIT_ONCE_CTX_RESERVED_BITS bits of the data are always zero. /// /// /// If INIT_ONCE_CHECK_ONLY is not specified and the function succeeds, the return value is TRUE. /// If INIT_ONCE_CHECK_ONLY is specified and initialization has completed, the return value is TRUE. /// Otherwise, the return value is FALSE. To get extended error information, call GetLastError. /// // BOOL WINAPI InitOnceBeginInitialize( _Inout_ LPINIT_ONCE lpInitOnce, _In_ DWORD dwFlags, _Out_ PBOOL fPending, _Out_opt_ LPVOID // *lpContext); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683487(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms683487")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitOnceBeginInitialize(ref INIT_ONCE lpInitOnce, INIT_ONCE_FLAGS dwFlags, [MarshalAs(UnmanagedType.Bool)] out bool fPending, out IntPtr lpContext); /// Completes one-time initialization started with the InitOnceBeginInitialize function. /// A pointer to the one-time initialization structure. /// /// This parameter can be one of the following flags. /// /// /// /// Value /// Meaning /// /// /// INIT_ONCE_ASYNC0x00000002UL /// /// Operate in asynchronous mode. This enables multiple completion attempts to execute in parallel. This flag must match the flag /// passed in the corresponding call to the InitOnceBeginInitialize function. This flag may not be combined with INIT_ONCE_INIT_FAILED. /// /// /// /// INIT_ONCE_INIT_FAILED0x00000004UL /// /// The initialization attempt failed. This flag may not be combined with INIT_ONCE_ASYNC. To fail an asynchronous initialization, /// merely abandon it (that is, do not call the InitOnceComplete function). /// /// /// /// /// /// /// A pointer to the data to be stored with the one-time initialization structure. This data is returned in the lpContext parameter /// passed to subsequent calls to the InitOnceBeginInitialize function. If lpContext points to a value, the low-order /// INIT_ONCE_CTX_RESERVED_BITS of the value must be zero. If lpContext points to a data structure, the data structure must be DWORD-aligned. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI InitOnceComplete( _Inout_ LPINIT_ONCE lpInitOnce, _In_ DWORD dwFlags, _In_opt_ LPVOID lpContext); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683491(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms683491")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitOnceComplete(ref INIT_ONCE lpInitOnce, INIT_ONCE_FLAGS dwFlags, IntPtr lpContext); /// /// Executes the specified function successfully one time. No other threads that specify the same one-time initialization structure /// can execute the specified function while it is being executed by the current thread. /// /// A pointer to the one-time initialization structure. /// A pointer to an application-defined InitOnceCallback function. /// A parameter to be passed to the callback function. /// /// A parameter that receives data stored with the one-time initialization structure upon success. The low-order /// INIT_ONCE_CTX_RESERVED_BITS bits of the data are always zero. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI InitOnceExecuteOnce( _Inout_ PINIT_ONCE InitOnce, _In_ PINIT_ONCE_FN InitFn, _Inout_opt_ PVOID Parameter, _Out_opt_ // LPVOID *Context); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683493(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms683493")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitOnceExecuteOnce(ref INIT_ONCE InitOnce, InitOnceCallback InitFn, [Optional] IntPtr Parameter, out IntPtr Context); /// Initializes a one-time initialization structure. /// A pointer to the one-time initialization structure. /// This function does not return a value. // VOID WINAPI InitOnceInitialize( _Out_ PINIT_ONCE InitOnce); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683495(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms683495")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitOnceInitialize(out INIT_ONCE InitOnce); /// /// /// Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 32-bit values and /// exchanges with another 32-bit value based on the outcome of the comparison. /// /// /// If you are exchanging pointer values, this function has been superseded by the InterlockedCompareExchangePointer function. /// /// To operate on 64-bit values, use the InterlockedCompareExchange64 function. /// /// A pointer to the destination value. /// The exchange value. /// The value to compare to Destination. /// The function returns the initial value of the Destination parameter. // LONG __cdecl InterlockedCompareExchange( _Inout_ LONG volatile *Destination, _In_ LONG Exchange, _In_ LONG Comparand); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683560(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms683560")] public static int InterlockedCompareExchange(ref int Destination, int Exchange, int Comparand) => System.Threading.Interlocked.CompareExchange(ref Destination, Exchange, Comparand); /// /// Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation. /// To operate on 64-bit values, use the InterlockedDecrement64 function. /// /// A pointer to the variable to be decremented. /// The function returns the resulting decremented value. // LONG __cdecl InterlockedDecrement( _Inout_ LONG volatile *Addend); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683580(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms683580")] public static int InterlockedDecrement(ref int Addend) => System.Threading.Interlocked.Decrement(ref Addend); /// /// Sets a 32-bit variable to the specified value as an atomic operation. /// To operate on a pointer variable, use the InterlockedExchangePointer function. /// To operate on a 16-bit variable, use the InterlockedExchange16 function. /// To operate on a 64-bit variable, use the InterlockedExchange64 function. /// /// /// A pointer to the value to be exchanged. The function sets this variable to Value, and returns its prior value. /// /// The value to be exchanged with the value pointed to by Target. /// The function returns the initial value of the Target parameter. // LONG __cdecl InterlockedExchange( _Inout_ LONG volatile *Target, _In_ LONG Value); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683590(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms683590")] public static int InterlockedExchange(ref int Target, int Value) => System.Threading.Interlocked.Exchange(ref Target, Value); /// /// Performs an atomic addition of two 32-bit values. /// To operate on 64-bit values, use the InterlockedExchangeAdd64 function. /// /// A pointer to a variable. The value of this variable will be replaced with the result of the operation. /// The value to be added to the variable pointed to by the Addend parameter. /// The function returns the initial value of the Addend parameter. // LONG __cdecl InterlockedExchangeAdd( _Inout_ LONG volatile *Addend, _In_ LONG Value); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683597(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms683597")] public static int InterlockedExchangeAdd(ref int Addend, int Value) => throw new NotImplementedException("Machine level export not found in Kernel32.dll or .NET assemblies."); /// /// Increments (increases by one) the value of the specified 32-bit variable as an atomic operation. /// To operate on 64-bit values, use the InterlockedIncrement64 function. /// /// A pointer to the variable to be incremented. /// The function returns the resulting incremented value. // LONG __cdecl InterlockedIncrement( _Inout_ LONG volatile *Addend); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683614(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms683614")] public static int InterlockedIncrement(ref int Addend) => System.Threading.Interlocked.Increment(ref Addend); /// Releases ownership of the specified critical section object. /// A pointer to the critical section object. /// This function does not return a value. // void WINAPI LeaveCriticalSection( _Inout_ LPCRITICAL_SECTION lpCriticalSection); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684169(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms684169")] public static extern void LeaveCriticalSection(ref CRITICAL_SECTION lpCriticalSection); /// Opens an existing named event object. /// /// The access to the event object. The function fails if the security descriptor of the specified object does not permit the /// requested access for the calling process. For a list of access rights, see Synchronization Object Security and Access Rights. /// /// /// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit /// this handle. /// /// /// The name of the event to be opened. Name comparisons are case sensitive. /// This function can open objects in a private namespace. For more information, see Object Namespaces. /// /// Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly open an object in the global or session /// namespace. The remainder of the name can contain any character except the backslash character (\). For more information, see /// Kernel Object Namespaces. /// /// /// Note Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the /// next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so /// that applications can support multiple users. /// /// /// /// If the function succeeds, the return value is a handle to the event object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI OpenEvent( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ LPCTSTR lpName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684305(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms684305")] public static extern SafeEventHandle OpenEvent(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName); /// Opens an existing named mutex object. /// /// The access to the mutex object. Only the SYNCHRONIZE access right is required to use a mutex; to change the mutex's /// security, specify MUTEX_ALL_ACCESS. The function fails if the security descriptor of the specified object does not permit /// the requested access for the calling process. For a list of access rights, see Synchronization Object Security and Access Rights. /// /// /// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit /// this handle. /// /// /// The name of the mutex to be opened. Name comparisons are case sensitive. /// This function can open objects in a private namespace. For more information, see Object Namespaces. /// /// Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly open an object in the global or session /// namespace. The remainder of the name can contain any character except the backslash character (\). For more information, see /// Kernel Object Namespaces. /// /// /// Note Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the /// next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so /// that applications can support multiple users. /// /// /// /// If the function succeeds, the return value is a handle to the mutex object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// If a named mutex does not exist, the function fails and GetLastError returns ERROR_FILE_NOT_FOUND. /// // HANDLE WINAPI OpenMutex( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ LPCTSTR lpName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684315(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms684315")] public static extern SafeMutexHandle OpenMutex(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName); /// Opens an existing named semaphore object. /// /// The access to the semaphore object. The function fails if the security descriptor of the specified object does not permit the /// requested access for the calling process. For a list of access rights, see Synchronization Object Security and Access Rights. /// /// /// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit /// this handle. /// /// /// The name of the semaphore to be opened. Name comparisons are case sensitive. /// This function can open objects in a private namespace. For more information, see Object Namespaces. /// /// Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly open an object in the global or session /// namespace. The remainder of the name can contain any character except the backslash character (\). For more information, see /// Kernel Object Namespaces. /// /// /// Note Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the /// next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so /// that applications can support multiple users. /// /// /// /// If the function succeeds, the return value is a handle to the semaphore object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI OpenSemaphore( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ LPCTSTR lpName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684326(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms684326")] public static extern SafeSemaphoreHandle OpenSemaphore(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName); /// Opens an existing named waitable timer object. /// /// The access to the timer object. The function fails if the security descriptor of the specified object does not permit the /// requested access for the calling process. For a list of access rights, see Synchronization Object Security and Access Rights. /// /// /// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit /// this handle. /// /// /// The name of the timer object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. /// This function can open objects in a private namespace. For more information, see Object Namespaces. /// /// Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly open an object in the global or session /// namespace. The remainder of the name can contain any character except the backslash character (\). For more information, see /// Kernel Object Namespaces. /// /// /// Note Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the /// next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so /// that applications can support multiple users. /// /// /// /// If the function succeeds, the return value is a handle to the timer object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HANDLE WINAPI OpenWaitableTimer( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ LPCTSTR lpTimerName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684337(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms684337")] public static extern SafeWaitableTimerHandle OpenWaitableTimer(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpTimerName); /// /// Sets the specified event object to the signaled state and then resets it to the nonsignaled state after releasing the appropriate /// number of waiting threads. /// /// /// A handle to the event object. The CreateEvent or OpenEvent function returns this handle. /// /// The handle must have the EVENT_MODIFY_STATE access right. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI PulseEvent( _In_ HANDLE hEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684914(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms684914")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool PulseEvent([In] SafeEventHandle hEvent); /// Releases ownership of the specified mutex object. /// A handle to the mutex object. The CreateMutex or OpenMutex function returns this handle. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI ReleaseMutex( _In_ HANDLE hMutex); https://msdn.microsoft.com/en-us/library/windows/desktop/ms685066(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms685066")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ReleaseMutex([In] SafeMutexHandle hMutex); /// Increases the count of the specified semaphore object by a specified amount. /// /// A handle to the semaphore object. The CreateSemaphore or OpenSemaphore function returns this handle. /// /// This handle must have the SEMAPHORE_MODIFY_STATE access right. For more information, see Synchronization Object Security /// and Access Rights. /// /// /// /// The amount by which the semaphore object's current count is to be increased. The value must be greater than zero. If the /// specified amount would cause the semaphore's count to exceed the maximum count that was specified when the semaphore was created, /// the count is not changed and the function returns FALSE. /// /// /// A pointer to a variable to receive the previous count for the semaphore. This parameter can be NULL if the previous count /// is not required. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI ReleaseSemaphore( _In_ HANDLE hSemaphore, _In_ LONG lReleaseCount, _Out_opt_ LPLONG lpPreviousCount); https://msdn.microsoft.com/en-us/library/windows/desktop/ms685071(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms685071")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ReleaseSemaphore([In] SafeSemaphoreHandle hSemaphore, int lReleaseCount, out int lpPreviousCount); /// Releases a slim reader/writer (SRW) lock that was acquired in exclusive mode. /// A pointer to the SRW lock. /// This function does not return a value. // VOID WINAPI ReleaseSRWLockExclusive( _Inout_ PSRWLOCK SRWLock); https://msdn.microsoft.com/en-us/library/windows/desktop/ms685076(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms685076")] public static extern void ReleaseSRWLockExclusive(ref SRWLOCK SRWLock); /// Releases a slim reader/writer (SRW) lock that was acquired in shared mode. /// A pointer to the SRW lock. /// This function does not return a value. // VOID WINAPI ReleaseSRWLockShared( _Inout_ PSRWLOCK SRWLock); https://msdn.microsoft.com/en-us/library/windows/desktop/ms685080(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms685080")] public static extern void ReleaseSRWLockShared(ref SRWLOCK SRWLock); /// Sets the specified event object to the nonsignaled state. /// /// A handle to the event object. The CreateEvent or OpenEvent function returns this handle. /// /// The handle must have the EVENT_MODIFY_STATE access right. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI ResetEvent( _In_ HANDLE hEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms685081(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms685081")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ResetEvent([In] SafeEventHandle hEvent); /// Sets the specified event object to the nonsignaled state. /// /// A handle to the event object. The CreateEvent or OpenEvent function returns this handle. /// /// The handle must have the EVENT_MODIFY_STATE access right. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI ResetEvent( _In_ HANDLE hEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms685081(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms685081")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ResetEvent([In] IntPtr hEvent); /// Sets the specified event object to the nonsignaled state. /// /// A handle to the event object. The CreateEvent or OpenEvent function returns this handle. /// /// The handle must have the EVENT_MODIFY_STATE access right. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI ResetEvent( _In_ HANDLE hEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms685081(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms685081")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ResetEvent([In] HEVENT hEvent); /// /// Sets the spin count for the specified critical section. Spinning means that when a thread tries to acquire a critical section /// that is locked, the thread enters a loop, checks to see if the lock is released, and if the lock is not released, the thread goes /// to sleep. /// /// A pointer to the critical section object. /// /// The spin count for the critical section object. On single-processor systems, the spin count is ignored and the critical section /// spin count is set to zero (0). On multiprocessor systems, if the critical section is unavailable, the calling thread spins /// dwSpinCount times before performing a wait operation on a semaphore associated with the critical section. If the critical section /// becomes free during the spin operation, the calling thread avoids the wait operation. /// /// The function returns the previous spin count for the critical section. // DWORD WINAPI SetCriticalSectionSpinCount( _Inout_ LPCRITICAL_SECTION lpCriticalSection, _In_ DWORD dwSpinCount); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686197(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686197")] public static extern uint SetCriticalSectionSpinCount(ref CRITICAL_SECTION lpCriticalSection, uint dwSpinCount); /// Sets the specified event object to the signaled state. /// /// A handle to the event object. The CreateEvent or OpenEvent function returns this handle. /// /// The handle must have the EVENT_MODIFY_STATE access right. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetEvent( _In_ HANDLE hEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686211(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686211")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetEvent([In] SafeEventHandle hEvent); /// Sets the specified event object to the signaled state. /// /// A handle to the event object. The CreateEvent or OpenEvent function returns this handle. /// /// The handle must have the EVENT_MODIFY_STATE access right. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetEvent( _In_ HANDLE hEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686211(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686211")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetEvent([In] IntPtr hEvent); /// Sets the specified event object to the signaled state. /// /// A handle to the event object. The CreateEvent or OpenEvent function returns this handle. /// /// The handle must have the EVENT_MODIFY_STATE access right. For more information, see Synchronization Object Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetEvent( _In_ HANDLE hEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686211(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686211")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetEvent([In] HEVENT hEvent); /// /// Activates the specified waitable timer. When the due time arrives, the timer is signaled and the thread that set the timer calls /// the optional completion routine. /// /// /// A handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle. /// /// The handle must have the TIMER_MODIFY_STATE access right. For more information, see Synchronization Object Security and /// Access Rights. /// /// /// /// The time after which the state of the timer is to be set to signaled, in 100 nanosecond intervals. Use the format described by /// the FILETIME structure. Positive values indicate absolute time. Be sure to use a UTC-based absolute time, as the system /// uses UTC-based time internally. Negative values indicate relative time. The actual timer accuracy depends on the capability of /// your hardware. For more information about UTC-based time, see System Time. /// /// /// The period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. If lPeriod is greater than zero, the /// timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled using the /// CancelWaitableTimer function or reset using SetWaitableTimer. If lPeriod is less than zero, the function fails. /// /// /// A pointer to an optional completion routine. The completion routine is application-defined function of type /// PTIMERAPCROUTINE to be executed when the timer is signaled. For more information on the timer callback function, see /// TimerAPCProc. For more information about APCs and thread pool threads, see Remarks. /// /// A pointer to a structure that is passed to the completion routine. /// /// If this parameter is TRUE, restores a system in suspended power conservation mode when the timer state is set to signaled. /// Otherwise, the system is not restored. If the system does not support a restore, the call succeeds, but GetLastError /// returns ERROR_NOT_SUPPORTED. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetWaitableTimer( _In_ HANDLE hTimer, _In_ const LARGE_INTEGER *pDueTime, _In_ LONG lPeriod, _In_opt_ PTIMERAPCROUTINE // pfnCompletionRoutine, _In_opt_ LPVOID lpArgToCompletionRoutine, _In_ BOOL fResume); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686289(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686289")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWaitableTimer([In] SafeWaitableTimerHandle hTimer, in FILETIME pDueTime, [Optional] int lPeriod, [Optional] TimerAPCProc pfnCompletionRoutine, [In, Optional] IntPtr lpArgToCompletionRoutine, [MarshalAs(UnmanagedType.Bool)] bool fResume = false); /// /// Activates the specified waitable timer. When the due time arrives, the timer is signaled and the thread that set the timer calls /// the optional completion routine. /// /// /// A handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle. /// /// The handle must have the TIMER_MODIFY_STATE access right. For more information, see Synchronization Object Security and /// Access Rights. /// /// /// /// The time after which the state of the timer is to be set to signaled, in 100 nanosecond intervals. Use the format described by /// the FILETIME structure. Positive values indicate absolute time. Be sure to use a UTC-based absolute time, as the system /// uses UTC-based time internally. Negative values indicate relative time. The actual timer accuracy depends on the capability of /// your hardware. For more information about UTC-based time, see System Time. /// /// /// The period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. If lPeriod is greater than zero, the /// timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled using the /// CancelWaitableTimer function or reset using SetWaitableTimer. If lPeriod is less than zero, the function fails. /// /// /// A pointer to an optional completion routine. The completion routine is application-defined function of type /// PTIMERAPCROUTINE to be executed when the timer is signaled. For more information on the timer callback function, see /// TimerAPCProc. For more information about APCs and thread pool threads, see Remarks. /// /// A pointer to a structure that is passed to the completion routine. /// /// If this parameter is TRUE, restores a system in suspended power conservation mode when the timer state is set to signaled. /// Otherwise, the system is not restored. If the system does not support a restore, the call succeeds, but GetLastError /// returns ERROR_NOT_SUPPORTED. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetWaitableTimer( _In_ HANDLE hTimer, _In_ const LARGE_INTEGER *pDueTime, _In_ LONG lPeriod, _In_opt_ PTIMERAPCROUTINE // pfnCompletionRoutine, _In_opt_ LPVOID lpArgToCompletionRoutine, _In_ BOOL fResume); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686289(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686289")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWaitableTimer([In] SafeWaitableTimerHandle hTimer, in long pDueTime, [Optional] int lPeriod, [Optional] TimerAPCProc pfnCompletionRoutine, [In, Optional] IntPtr lpArgToCompletionRoutine, [MarshalAs(UnmanagedType.Bool)] bool fResume = false); /// /// Activates the specified waitable timer and provides context information for the timer. When the due time arrives, the timer is /// signaled and the thread that set the timer calls the optional completion routine. /// /// /// A handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle. /// /// The handle must have the TIMER_MODIFY_STATE access right. For more information, see Synchronization Object Security and /// Access Rights. /// /// /// /// The time after which the state of the timer is to be set to signaled, in 100 nanosecond intervals. Use the format described by /// the FILETIME structure. Positive values indicate absolute time. Be sure to use a UTC-based absolute time, as the system /// uses UTC-based time internally. Negative values indicate relative time. The actual timer accuracy depends on the capability of /// your hardware. For more information about UTC-based time, see System Time. /// /// /// The period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. If lPeriod is greater than zero, the /// timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled using the /// CancelWaitableTimer function or reset using SetWaitableTimerEx. If lPeriod is less than zero, the function fails. /// /// /// A pointer to an optional completion routine. The completion routine is application-defined function of type /// PTIMERAPCROUTINE to be executed when the timer is signaled. For more information on the timer callback function, see /// TimerAPCProc. For more information about APCs and thread pool threads, see Remarks. /// /// A pointer to a structure that is passed to the completion routine. /// Pointer to a REASON_CONTEXT structure that contains context information for the timer. /// The tolerable delay for expiration time, in milliseconds. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetWaitableTimerEx( _In_ HANDLE hTimer, _In_ const LARGE_INTEGER *lpDueTime, _In_ LONG lPeriod, _In_ PTIMERAPCROUTINE // pfnCompletionRoutine, _In_ LPVOID lpArgToCompletionRoutine, _In_ PREASON_CONTEXT WakeContext, _In_ ULONG TolerableDelay); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405521(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "dd405521")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWaitableTimerEx([In] SafeWaitableTimerHandle hTimer, in FILETIME lpDueTime, [Optional] int lPeriod, [Optional] TimerAPCProc pfnCompletionRoutine, [In, Optional] IntPtr lpArgToCompletionRoutine, [In] REASON_CONTEXT WakeContext, uint TolerableDelay); /// /// Activates the specified waitable timer and provides context information for the timer. When the due time arrives, the timer is /// signaled and the thread that set the timer calls the optional completion routine. /// /// /// A handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle. /// /// The handle must have the TIMER_MODIFY_STATE access right. For more information, see Synchronization Object Security and /// Access Rights. /// /// /// /// The time after which the state of the timer is to be set to signaled, in 100 nanosecond intervals. Use the format described by /// the FILETIME structure. Positive values indicate absolute time. Be sure to use a UTC-based absolute time, as the system /// uses UTC-based time internally. Negative values indicate relative time. The actual timer accuracy depends on the capability of /// your hardware. For more information about UTC-based time, see System Time. /// /// /// The period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. If lPeriod is greater than zero, the /// timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled using the /// CancelWaitableTimer function or reset using SetWaitableTimerEx. If lPeriod is less than zero, the function fails. /// /// /// A pointer to an optional completion routine. The completion routine is application-defined function of type /// PTIMERAPCROUTINE to be executed when the timer is signaled. For more information on the timer callback function, see /// TimerAPCProc. For more information about APCs and thread pool threads, see Remarks. /// /// A pointer to a structure that is passed to the completion routine. /// Pointer to a REASON_CONTEXT structure that contains context information for the timer. /// The tolerable delay for expiration time, in milliseconds. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetWaitableTimerEx( _In_ HANDLE hTimer, _In_ const LARGE_INTEGER *lpDueTime, _In_ LONG lPeriod, _In_ PTIMERAPCROUTINE // pfnCompletionRoutine, _In_ LPVOID lpArgToCompletionRoutine, _In_ PREASON_CONTEXT WakeContext, _In_ ULONG TolerableDelay); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405521(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "dd405521")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWaitableTimerEx([In] SafeWaitableTimerHandle hTimer, in long lpDueTime, [Optional] int lPeriod, [Optional] TimerAPCProc pfnCompletionRoutine, [In, Optional] IntPtr lpArgToCompletionRoutine, [In] REASON_CONTEXT WakeContext, uint TolerableDelay); /// /// Activates the specified waitable timer and provides context information for the timer. When the due time arrives, the timer is /// signaled and the thread that set the timer calls the optional completion routine. /// /// /// A handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle. /// /// The handle must have the TIMER_MODIFY_STATE access right. For more information, see Synchronization Object Security and /// Access Rights. /// /// /// /// The time after which the state of the timer is to be set to signaled, in 100 nanosecond intervals. Use the format described by /// the FILETIME structure. Positive values indicate absolute time. Be sure to use a UTC-based absolute time, as the system /// uses UTC-based time internally. Negative values indicate relative time. The actual timer accuracy depends on the capability of /// your hardware. For more information about UTC-based time, see System Time. /// /// /// The period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. If lPeriod is greater than zero, the /// timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled using the /// CancelWaitableTimer function or reset using SetWaitableTimerEx. If lPeriod is less than zero, the function fails. /// /// /// A pointer to an optional completion routine. The completion routine is application-defined function of type /// PTIMERAPCROUTINE to be executed when the timer is signaled. For more information on the timer callback function, see /// TimerAPCProc. For more information about APCs and thread pool threads, see Remarks. /// /// A pointer to a structure that is passed to the completion routine. /// Pointer to a REASON_CONTEXT structure that contains context information for the timer. /// The tolerable delay for expiration time, in milliseconds. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetWaitableTimerEx( _In_ HANDLE hTimer, _In_ const LARGE_INTEGER *lpDueTime, _In_ LONG lPeriod, _In_ PTIMERAPCROUTINE // pfnCompletionRoutine, _In_ LPVOID lpArgToCompletionRoutine, _In_ PREASON_CONTEXT WakeContext, _In_ ULONG TolerableDelay); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405521(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "dd405521")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWaitableTimerEx([In] SafeWaitableTimerHandle hTimer, in FILETIME lpDueTime, [Optional] int lPeriod, [Optional] TimerAPCProc pfnCompletionRoutine, [In, Optional] IntPtr lpArgToCompletionRoutine, [Optional] IntPtr WakeContext, uint TolerableDelay); /// /// Activates the specified waitable timer and provides context information for the timer. When the due time arrives, the timer is /// signaled and the thread that set the timer calls the optional completion routine. /// /// /// A handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle. /// /// The handle must have the TIMER_MODIFY_STATE access right. For more information, see Synchronization Object Security and /// Access Rights. /// /// /// /// The time after which the state of the timer is to be set to signaled, in 100 nanosecond intervals. Use the format described by /// the FILETIME structure. Positive values indicate absolute time. Be sure to use a UTC-based absolute time, as the system /// uses UTC-based time internally. Negative values indicate relative time. The actual timer accuracy depends on the capability of /// your hardware. For more information about UTC-based time, see System Time. /// /// /// The period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. If lPeriod is greater than zero, the /// timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled using the /// CancelWaitableTimer function or reset using SetWaitableTimerEx. If lPeriod is less than zero, the function fails. /// /// /// A pointer to an optional completion routine. The completion routine is application-defined function of type /// PTIMERAPCROUTINE to be executed when the timer is signaled. For more information on the timer callback function, see /// TimerAPCProc. For more information about APCs and thread pool threads, see Remarks. /// /// A pointer to a structure that is passed to the completion routine. /// Pointer to a REASON_CONTEXT structure that contains context information for the timer. /// The tolerable delay for expiration time, in milliseconds. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI SetWaitableTimerEx( _In_ HANDLE hTimer, _In_ const LARGE_INTEGER *lpDueTime, _In_ LONG lPeriod, _In_ PTIMERAPCROUTINE // pfnCompletionRoutine, _In_ LPVOID lpArgToCompletionRoutine, _In_ PREASON_CONTEXT WakeContext, _In_ ULONG TolerableDelay); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405521(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "dd405521")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWaitableTimerEx([In] SafeWaitableTimerHandle hTimer, in long lpDueTime, [Optional] int lPeriod, [Optional] TimerAPCProc pfnCompletionRoutine, [In, Optional] IntPtr lpArgToCompletionRoutine, [Optional] IntPtr WakeContext, uint TolerableDelay); /// Signals one object and waits on another object as a single operation. /// /// A handle to the object to be signaled. This object can be a semaphore, a mutex, or an event. /// /// If the handle is a semaphore, the SEMAPHORE_MODIFY_STATE access right is required. If the handle is an event, the /// EVENT_MODIFY_STATE access right is required. If the handle is a mutex and the caller does not own the mutex, the function /// fails with ERROR_NOT_OWNER. /// /// /// /// A handle to the object to wait on. The SYNCHRONIZE access right is required; for more information, see Synchronization /// Object Security and Access Rights. For a list of the object types whose handles you can specify, see the Remarks section. /// /// /// The time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled /// and no completion or asynchronous procedure call (APC) objects are queued. If dwMilliseconds is zero, the function tests the /// object's state, checks for queued completion routines or APCs, and returns immediately. If dwMilliseconds is INFINITE, the /// function's time-out interval never elapses. /// /// /// /// If this parameter is TRUE, the function returns when the system queues an I/O completion routine or APC function, and the /// thread calls the function. If FALSE, the function does not return, and the thread does not call the completion routine or /// APC function. /// /// /// A completion routine is queued when the function call that queued the APC has completed. This function returns and the completion /// routine is called only if bAlertable is TRUE, and the calling thread is the thread that queued the APC. /// /// /// /// /// If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values. /// /// /// /// /// Return code/value /// Description /// /// /// WAIT_ABANDONED = 0x00000080L /// /// The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread /// terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.If the mutex was /// protecting persistent state information, you should check it for consistency. /// /// /// /// WAIT_IO_COMPLETION = 0x000000C0L /// The wait was ended by one or more user-mode asynchronous procedure calls (APC) queued to the thread. /// /// /// WAIT_OBJECT_0 = 0x00000000L /// The state of the specified object is signaled. /// /// /// WAIT_TIMEOUT = 0x00000102L /// The time-out interval elapsed, and the object's state is nonsignaled. /// /// /// WAIT_FAILED = (DWORD)0xFFFFFFFF /// The function has failed. To get extended error information, call GetLastError. /// /// /// /// // DWORD WINAPI SignalObjectAndWait( _In_ HANDLE hObjectToSignal, _In_ HANDLE hObjectToWaitOn, _In_ DWORD dwMilliseconds, _In_ BOOL // bAlertable); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686293(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms686293")] public static WAIT_STATUS SignalObjectAndWait([In] ISyncHandle hObjectToSignal, [In] ISyncHandle hObjectToWaitOn, uint dwMilliseconds, bool bAlertable) => SignalObjectAndWait(hObjectToSignal?.DangerousGetHandle() ?? IntPtr.Zero, hObjectToWaitOn?.DangerousGetHandle() ?? IntPtr.Zero, dwMilliseconds, bAlertable); /// /// Suspends the execution of the current thread until the time-out interval elapses. /// To enter an alertable wait state, use the SleepEx function. /// /// /// The time interval for which execution is to be suspended, in milliseconds. /// /// A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If /// there are no other threads ready to run, the function returns immediately, and the thread continues execution. /// /// /// Windows XP: A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal /// priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, /// and the thread continues execution. This behavior changed starting with Windows Server 2003. /// /// A value of INFINITE indicates that the suspension should not time out. /// /// This function does not return a value. // VOID WINAPI Sleep( _In_ DWORD dwMilliseconds); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686298")] public static extern void Sleep(uint dwMilliseconds); /// Sleeps on the specified condition variable and releases the specified critical section as an atomic operation. /// /// A pointer to the condition variable. This variable must be initialized using the InitializeConditionVariable function. /// /// /// A pointer to the critical section object. This critical section must be entered exactly once by the caller at the time /// SleepConditionVariableCS is called. /// /// /// The time-out interval, in milliseconds. If the time-out interval elapses, the function re-acquires the critical section and /// returns zero. If dwMilliseconds is zero, the function tests the states of the specified objects and returns immediately. If /// dwMilliseconds is INFINITE, the function's time-out interval never elapses. For more information, see Remarks. /// /// /// If the function succeeds, the return value is nonzero. /// /// If the function fails or the time-out interval elapses, the return value is zero. To get extended error information, call /// GetLastError. Possible error codes include ERROR_TIMEOUT, which indicates that the time-out interval has elapsed /// before another thread has attempted to wake the sleeping thread. /// /// // BOOL WINAPI SleepConditionVariableCS( _Inout_ PCONDITION_VARIABLE ConditionVariable, _Inout_ PCRITICAL_SECTION CriticalSection, // _In_ DWORD dwMilliseconds); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686301(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686301")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SleepConditionVariableCS(ref CONDITION_VARIABLE ConditionVariable, ref CRITICAL_SECTION CriticalSection, uint dwMilliseconds); /// Sleeps on the specified condition variable and releases the specified lock as an atomic operation. /// /// A pointer to the condition variable. This variable must be initialized using the InitializeConditionVariable function. /// /// A pointer to the lock. This lock must be held in the manner specified by the Flags parameter. /// /// The time-out interval, in milliseconds. The function returns if the interval elapses. If dwMilliseconds is zero, the function /// tests the states of the specified objects and returns immediately. If dwMilliseconds is INFINITE, the function's time-out /// interval never elapses. /// /// /// If this parameter is CONDITION_VARIABLE_LOCKMODE_SHARED, the SRW lock is in shared mode. Otherwise, the lock is in /// exclusive mode. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// If the timeout expires the function returns FALSE and GetLastError returns ERROR_TIMEOUT. /// // BOOL WINAPI SleepConditionVariableSRW( _Inout_ PCONDITION_VARIABLE ConditionVariable, _Inout_ PSRWLOCK SRWLock, _In_ DWORD // dwMilliseconds, _In_ ULONG Flags); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686304(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686304")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SleepConditionVariableSRW(ref CONDITION_VARIABLE ConditionVariable, ref SRWLOCK SRWLock, uint dwMilliseconds, CONDITION_VARIABLE_FLAGS Flags); /// Suspends the current thread until the specified condition is met. Execution resumes when one of the following occurs: /// /// The time interval for which execution is to be suspended, in milliseconds. /// /// A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If /// there are no other threads ready to run, the function returns immediately, and the thread continues execution. /// /// /// Windows XP: A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal /// priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, /// and the thread continues execution. This behavior changed starting with Windows Server 2003. /// /// A value of INFINITE indicates that the suspension should not time out. /// /// /// /// If this parameter is FALSE, the function does not return until the time-out period has elapsed. If an I/O completion callback /// occurs, the function does not return and the I/O completion function is not executed. If an APC is queued to the thread, the /// function does not return and the APC function is not executed. /// /// /// If the parameter is TRUE and the thread that called this function is the same thread that called the extended I/O function ( /// ReadFileEx or WriteFileEx), the function returns when either the time-out period has elapsed or when an I/O /// completion callback function occurs. If an I/O completion callback occurs, the I/O completion function is called. If an APC is /// queued to the thread ( QueueUserAPC), the function returns when either the timer-out period has elapsed or when the APC /// function is called. /// /// /// /// The return value is zero if the specified time interval expired. /// /// The return value is WAIT_IO_COMPLETION if the function returned due to one or more I/O completion callback functions. This /// can happen only if bAlertable is TRUE, and if the thread that called the SleepEx function is the same thread that called /// the extended I/O function. /// /// // DWORD WINAPI SleepEx( _In_ DWORD dwMilliseconds, _In_ BOOL bAlertable); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686307(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686307")] public static extern uint SleepEx(uint dwMilliseconds, [MarshalAs(UnmanagedType.Bool)] bool bAlertable); /// /// Attempts to acquire a slim reader/writer (SRW) lock in exclusive mode. If the call is successful, the calling thread takes /// ownership of the lock. /// /// A pointer to the SRW lock. /// /// If the lock is successfully acquired, the return value is nonzero. /// if the current thread could not acquire the lock, the return value is zero. /// // BOOLEAN WINAPI TryAcquireSRWLockExclusive( _Inout_ PSRWLOCK SRWLock); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405523(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "dd405523")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool TryAcquireSRWLockExclusive(ref SRWLOCK SRWLock); /// /// Attempts to acquire a slim reader/writer (SRW) lock in shared mode. If the call is successful, the calling thread takes ownership /// of the lock. /// /// A pointer to the SRW lock. /// /// If the lock is successfully acquired, the return value is nonzero. /// if the current thread could not acquire the lock, the return value is zero. /// // BOOLEAN WINAPI TryAcquireSRWLockShared( _Inout_ PSRWLOCK SRWLock); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405524(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "dd405524")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool TryAcquireSRWLockShared(ref SRWLOCK SRWLock); /// /// Attempts to enter a critical section without blocking. If the call is successful, the calling thread takes ownership of the /// critical section. /// /// A pointer to the critical section object. /// /// /// If the critical section is successfully entered or the current thread already owns the critical section, the return value is nonzero. /// /// If another thread already owns the critical section, the return value is zero. /// // BOOL WINAPI TryEnterCriticalSection( _Inout_ LPCRITICAL_SECTION lpCriticalSection); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686857(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686857")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool TryEnterCriticalSection(ref CRITICAL_SECTION lpCriticalSection); /// /// Cancels a registered wait operation issued by the function. /// To use a completion event, call the UnregisterWaitEx function. /// /// The wait handle. This handle is returned by the RegisterWaitForSingleObject function. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI UnregisterWait( _In_ HANDLE WaitHandle); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686870(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms686870")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool UnregisterWait([In] SafeRegisteredWaitHandle WaitHandle); /// /// Waits until one or all of the specified objects are in the signaled state or the time-out interval elapses. /// To enter an alertable wait state, use the WaitForMultipleObjectsEx function. /// /// /// /// An array of object handles. For a list of the object types whose handles can be specified, see the following Remarks section. The /// array can contain handles to objects of different types. It may not contain multiple copies of the same handle. /// /// If one of these handles is closed while the wait is still pending, the function's behavior is undefined. /// The handles must have the SYNCHRONIZE access right. For more information, see Standard Access Rights. /// /// /// If this parameter is TRUE, the function returns when the state of all objects in the lpHandles array is signaled. If /// FALSE, the function returns when the state of any one of the objects is set to signaled. In the latter case, the return /// value indicates the object whose state caused the function to return. /// /// /// The time-out interval, in milliseconds. If a nonzero value is specified, the function waits until the specified objects are /// signaled or the interval elapses. If dwMilliseconds is zero, the function does not enter a wait state if the specified objects /// are not signaled; it always returns immediately. If dwMilliseconds is INFINITE, the function will return only when the /// specified objects are signaled. /// /// /// /// If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following /// values. (Note that WAIT_OBJECT_0 is defined as 0 and WAIT_ABANDONED_0 is defined as 0x00000080L.) /// /// /// /// /// Return code/value /// Description /// /// /// WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1) /// /// If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If bWaitAll is FALSE, the /// return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one /// object became signaled during the call, this is the array index of the signaled object with the smallest index value of all the /// signaled objects. /// /// /// /// WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1) /// /// If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the /// objects is an abandoned mutex object. If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lpHandles array /// index of an abandoned mutex object that satisfied the wait. Ownership of the mutex object is granted to the calling thread, and /// the mutex is set to nonsignaled.If a mutex was protecting persistent state information, you should check it for consistency. /// /// /// /// WAIT_TIMEOUT0x00000102L /// The time-out interval elapsed and the conditions specified by the bWaitAll parameter are not satisfied. /// /// /// WAIT_FAILED(DWORD)0xFFFFFFFF /// The function has failed. To get extended error information, call GetLastError. /// /// /// /// // DWORD WINAPI WaitForMultipleObjects( _In_ DWORD nCount, _In_ const HANDLE *lpHandles, _In_ BOOL bWaitAll, _In_ DWORD // dwMilliseconds); https://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms687025")] public static WAIT_STATUS WaitForMultipleObjects(IEnumerable lpHandles, bool bWaitAll, uint dwMilliseconds) where T : ISyncHandle { var h = lpHandles?.Select(i => i.DangerousGetHandle()).ToArray(); return WaitForMultipleObjects((uint)(h?.Length ?? 0), h, bWaitAll, dwMilliseconds); } /// /// Waits until one or all of the specified objects are in the signaled state, an I/O completion routine or asynchronous procedure /// call (APC) is queued to the thread, or the time-out interval elapses. /// /// /// /// An array of object handles. For a list of the object types whose handles can be specified, see the following Remarks section. The /// array can contain handles of objects of different types. It may not contain multiple copies of the same handle. /// /// If one of these handles is closed while the wait is still pending, the function's behavior is undefined. /// The handles must have the SYNCHRONIZE access right. For more information, see Standard Access Rights. /// /// /// If this parameter is TRUE, the function returns when the state of all objects in the lpHandles array is set to signaled. /// If FALSE, the function returns when the state of any one of the objects is set to signaled. In the latter case, the return /// value indicates the object whose state caused the function to return. /// /// /// The time-out interval, in milliseconds. If a nonzero value is specified, the function waits until the specified objects are /// signaled, an I/O completion routine or APC is queued, or the interval elapses. If dwMilliseconds is zero, the function does not /// enter a wait state if the criteria is not met; it always returns immediately. If dwMilliseconds is INFINITE, the function /// will return only when the specified objects are signaled or an I/O completion routine or APC is queued. /// /// /// /// If this parameter is TRUE and the thread is in the waiting state, the function returns when the system queues an I/O /// completion routine or APC, and the thread runs the routine or function. Otherwise, the function does not return and the /// completion routine or APC function is not executed. /// /// /// A completion routine is queued when the ReadFileEx or WriteFileEx function in which it was specified has completed. /// The wait function returns and the completion routine is called only if bAlertable is TRUE and the calling thread is the /// thread that initiated the read or write operation. An APC is queued when you call QueueUserAPC. /// /// /// /// /// If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following /// values. (Note that WAIT_OBJECT_0 is defined as 0 and WAIT_ABANDONED_0 is defined as 0x00000080L.) /// /// /// /// /// Return code/value /// Description /// /// /// WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1) /// /// If bWaitAll is TRUE, a return value in this range indicates that the state of all specified objects is signaled. If bWaitAll is /// FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more /// than one object became signaled during the call, this is the array index of the signaled object with the smallest index value of /// all the signaled objects. /// /// /// /// WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1) /// /// If bWaitAll is TRUE, a return value in this range indicates that the state of all specified objects is signaled, and at least one /// of the objects is an abandoned mutex object. If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the /// lpHandles array index of an abandoned mutex object that satisfied the wait. Ownership of the mutex object is granted to the /// calling thread, and the mutex is set to nonsignaled.If a mutex was protecting persistent state information, you should check it /// for consistency. /// /// /// /// WAIT_IO_COMPLETION0x000000C0L /// The wait was ended by one or more user-mode asynchronous procedure calls (APC) queued to the thread. /// /// /// WAIT_TIMEOUT0x00000102L /// /// The time-out interval elapsed, the conditions specified by the bWaitAll parameter were not satisfied, and no completion routines /// are queued. /// /// /// /// WAIT_FAILED(DWORD)0xFFFFFFFF /// The function has failed. To get extended error information, call GetLastError. /// /// /// /// // DWORD WINAPI WaitForMultipleObjectsEx( _In_ DWORD nCount, _In_ const HANDLE *lpHandles, _In_ BOOL bWaitAll, _In_ DWORD // dwMilliseconds, _In_ BOOL bAlertable); https://msdn.microsoft.com/en-us/library/windows/desktop/ms687028(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms687028")] public static WAIT_STATUS WaitForMultipleObjectsEx(IEnumerable lpHandles, bool bWaitAll, uint dwMilliseconds, bool bAlertable) where T : ISyncHandle { var h = lpHandles?.Select(i => i.DangerousGetHandle()).ToArray(); return WaitForMultipleObjectsEx((uint)(h?.Length ?? 0), h, bWaitAll, dwMilliseconds, bAlertable); } /// /// Waits until the specified object is in the signaled state or the time-out interval elapses. /// To enter an alertable wait state, use the WaitForSingleObjectEx function. To wait for multiple objects, use WaitForMultipleObjects. /// /// /// A handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section. /// If this handle is closed while the wait is still pending, the function's behavior is undefined. /// The handle must have the SYNCHRONIZE access right. For more information, see Standard Access Rights. /// /// /// /// The time-out interval, in milliseconds. If a nonzero value is specified, the function waits until the object is signaled or the /// interval elapses. If dwMilliseconds is zero, the function does not enter a wait state if the object is not signaled; it always /// returns immediately. If dwMilliseconds is INFINITE, the function will return only when the object is signaled. /// /// /// Windows XP, Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 and Windows Server 2008 R2: The /// dwMilliseconds value does include time spent in low-power states. For example, the timeout does keep counting down while the /// computer is asleep. /// /// /// Windows 8, Windows Server 2012, Windows 8.1, Windows Server 2012 R2, Windows 10 and Windows Server 2016: The /// dwMilliseconds value does not include time spent in low-power states. For example, the timeout does not keep counting down while /// the computer is asleep. /// /// /// /// /// If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values. /// /// /// /// /// Return code/value /// Description /// /// /// WAIT_ABANDONED0x00000080L /// /// The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread /// terminated. Ownership of the mutex object is granted to the calling thread and the mutex state is set to nonsignaled.If the mutex /// was protecting persistent state information, you should check it for consistency. /// /// /// /// WAIT_OBJECT_00x00000000L /// The state of the specified object is signaled. /// /// /// WAIT_TIMEOUT0x00000102L /// The time-out interval elapsed, and the object's state is nonsignaled. /// /// /// WAIT_FAILED(DWORD)0xFFFFFFFF /// The function has failed. To get extended error information, call GetLastError. /// /// /// /// // DWORD WINAPI WaitForSingleObject( _In_ HANDLE hHandle, _In_ DWORD dwMilliseconds); https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms687032")] public static WAIT_STATUS WaitForSingleObject([In] ISyncHandle hHandle, uint dwMilliseconds) => WaitForSingleObject(hHandle?.DangerousGetHandle() ?? IntPtr.Zero, dwMilliseconds); /// /// /// Waits until the specified object is in the signaled state, an I/O completion routine or asynchronous procedure call (APC) is /// queued to the thread, or the time-out interval elapses. /// /// To wait for multiple objects, use the WaitForMultipleObjectsEx. /// /// /// A handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section. /// If this handle is closed while the wait is still pending, the function's behavior is undefined. /// The handle must have the SYNCHRONIZE access right. For more information, see Standard Access Rights. /// /// /// The time-out interval, in milliseconds. If a nonzero value is specified, the function waits until the object is signaled, an I/O /// completion routine or APC is queued, or the interval elapses. If dwMilliseconds is zero, the function does not enter a wait state /// if the criteria is not met; it always returns immediately. If dwMilliseconds is INFINITE, the function will return only /// when the object is signaled or an I/O completion routine or APC is queued. /// /// /// /// If this parameter is TRUE and the thread is in the waiting state, the function returns when the system queues an I/O /// completion routine or APC, and the thread runs the routine or function. Otherwise, the function does not return, and the /// completion routine or APC function is not executed. /// /// /// A completion routine is queued when the ReadFileEx or WriteFileEx function in which it was specified has completed. /// The wait function returns and the completion routine is called only if bAlertable is TRUE, and the calling thread is the /// thread that initiated the read or write operation. An APC is queued when you call QueueUserAPC. /// /// /// /// /// If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values. /// /// /// /// /// Return code/value /// Description /// /// /// WAIT_ABANDONED0x00000080L /// /// The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread /// terminated. Ownership of the mutex object is granted to the calling thread and the mutex is set to nonsignaled.If the mutex was /// protecting persistent state information, you should check it for consistency. /// /// /// /// WAIT_IO_COMPLETION0x000000C0L /// The wait was ended by one or more user-mode asynchronous procedure calls (APC) queued to the thread. /// /// /// WAIT_OBJECT_00x00000000L /// The state of the specified object is signaled. /// /// /// WAIT_TIMEOUT0x00000102L /// The time-out interval elapsed, and the object's state is nonsignaled. /// /// /// WAIT_FAILED(DWORD)0xFFFFFFFF /// The function has failed. To get extended error information, call GetLastError. /// /// /// /// // DWORD WINAPI WaitForSingleObjectEx( _In_ HANDLE hHandle, _In_ DWORD dwMilliseconds, _In_ BOOL bAlertable); https://msdn.microsoft.com/en-us/library/windows/desktop/ms687036(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms687036")] public static WAIT_STATUS WaitForSingleObjectEx([In] ISyncHandle hHandle, uint dwMilliseconds, bool bAlertable) => WaitForSingleObjectEx(hHandle?.DangerousGetHandle() ?? IntPtr.Zero, dwMilliseconds, bAlertable); /// Waits for the value at the specified address to change. /// /// The address on which to wait. If the value at Address differs from the value at CompareAddress, the function returns immediately. /// If the values are the same, the function does not return until another thread in the same process signals that the value at /// Address has changed by calling WakeByAddressSingle or WakeByAddressAll or the timeout elapses, whichever comes first. /// /// /// A pointer to the location of the previously observed value at Address. The function returns when the value at Address differs /// from the value at CompareAddress. /// /// The size of the value, in bytes. This parameter can be 1, 2, 4, or 8. /// /// The number of milliseconds to wait before the operation times out. If this parameter is INFINITE, the thread waits indefinitely. /// /// /// TRUE if the wait succeeded. If the operation fails, the function returns FALSE. If the wait fails, call GetLastError to /// obtain extended error information. In particular, if the operation times out, GetLastError returns ERROR_TIMEOUT. /// // BOOL WINAPI WaitOnAddress( _In_ VOID volatile *Address, _In_ PVOID CompareAddress, _In_ SIZE_T AddressSize, _In_opt_ DWORD // dwMilliseconds); https://msdn.microsoft.com/en-us/library/windows/desktop/hh706898(v=vs.85).aspx [DllImport(Lib.KernelBase, SetLastError = true, ExactSpelling = true)] [PInvokeData("SynchAPI.h", MSDNShortId = "hh706898")] [return: MarshalAs(UnmanagedType.Bool)] public static extern unsafe bool WaitOnAddress(void* Address, void* CompareAddress, SizeT AddressSize, uint dwMilliseconds); /// Wake all threads waiting on the specified condition variable. /// A pointer to the condition variable. /// This function does not return a value. // VOID WINAPI WakeAllConditionVariable( _Inout_ PCONDITION_VARIABLE ConditionVariable); https://msdn.microsoft.com/en-us/library/windows/desktop/ms687076(v=vs.85).aspx [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms687076")] public static extern void WakeAllConditionVariable(ref CONDITION_VARIABLE ConditionVariable); /// Wakes all threads that are waiting for the value of an address to change. /// /// The address to signal. If any threads have previously called WaitOnAddress for this address, the system wakes all of the /// waiting threads. /// /// This function does not return a value. // VOID WINAPI WakeByAddressAll( _In_ PVOID Address); https://msdn.microsoft.com/en-us/library/windows/desktop/hh706899(v=vs.85).aspx [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true)] [PInvokeData("SynchAPI.h", MSDNShortId = "hh706899")] public static extern unsafe void WakeByAddressAll(void* Address); /// Wakes one thread that is waiting for the value of an address to change. /// /// The address to signal. If another thread has previously called WaitOnAddress for this address, the system wakes the /// waiting thread. If multiple threads are waiting for this address, the system wakes the first thread to wait. /// /// This function does not return a value. // VOID WINAPI WakeByAddressSingle( _In_ PVOID Address); https://msdn.microsoft.com/en-us/library/windows/desktop/hh706900(v=vs.85).aspx [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true)] [PInvokeData("SynchAPI.h", MSDNShortId = "hh706900")] public static extern unsafe void WakeByAddressSingle(void* Address); /// Wake a single thread waiting on the specified condition variable. /// A pointer to the condition variable. /// This function does not return a value. // VOID WINAPI WakeConditionVariable( _Inout_ PCONDITION_VARIABLE ConditionVariable); https://msdn.microsoft.com/en-us/library/windows/desktop/ms687080(v=vs.85).aspx [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms687080")] public static extern void WakeConditionVariable(ref CONDITION_VARIABLE ConditionVariable); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] private static extern WAIT_STATUS SignalObjectAndWait([In] IntPtr hObjectToSignal, [In] IntPtr hObjectToWaitOn, uint dwMilliseconds, [MarshalAs(UnmanagedType.Bool)] bool bAlertable); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] private static extern WAIT_STATUS WaitForMultipleObjects(uint nCount, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.SysInt, SizeParamIndex = 0)] IntPtr[] lpHandles, [MarshalAs(UnmanagedType.Bool)] bool bWaitAll, uint dwMilliseconds); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] private static extern WAIT_STATUS WaitForMultipleObjectsEx(uint nCount, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.SysInt, SizeParamIndex = 0)] IntPtr[] lpHandles, [MarshalAs(UnmanagedType.Bool)] bool bWaitAll, uint dwMilliseconds, [MarshalAs(UnmanagedType.Bool)] bool bAlertable); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] private static extern WAIT_STATUS WaitForSingleObject([In] IntPtr hHandle, uint dwMilliseconds); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] private static extern WAIT_STATUS WaitForSingleObjectEx([In] IntPtr hHandle, uint dwMilliseconds, [MarshalAs(UnmanagedType.Bool)] bool bAlertable); /// A condition variable. [StructLayout(LayoutKind.Sequential)] public struct CONDITION_VARIABLE { private readonly IntPtr ptr; } /// A critical section object. [StructLayout(LayoutKind.Sequential)] public struct CRITICAL_SECTION { private readonly IntPtr DebugInfo; private readonly int LockCount; private readonly int RecursionCount; private readonly IntPtr OwningThread; private readonly IntPtr LockSemaphore; private readonly UIntPtr SpinCount; } /// A one-time initialization structure. [StructLayout(LayoutKind.Sequential)] public struct INIT_ONCE { private readonly IntPtr ptr; /// public static readonly INIT_ONCE INIT_ONCE_STATIC_INIT = new INIT_ONCE(); } /// /// Contains information about a power request. This structure is used by the PowerCreateRequest and SetWaitableTimerEx functions. /// // typedef struct _REASON_CONTEXT { ULONG Version; DWORD Flags; union { struct { HMODULE LocalizedReasonModule; ULONG // LocalizedReasonId; ULONG ReasonStringCount; LPWSTR *ReasonStrings; } Detailed; LPWSTR SimpleReasonString; } Reason;} // REASON_CONTEXT, *PREASON_CONTEXT; https://msdn.microsoft.com/en-us/library/windows/desktop/dd405536(v=vs.85).aspx [PInvokeData("MinWinBase.h", MSDNShortId = "dd405536")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public class REASON_CONTEXT : IDisposable { /// The version number of the structure. This parameter must be set to DIAGNOSTIC_REASON_VERSION. public DIAGNOSTIC_REASON_VERSION Version; /// /// The format of the reason for the power request. This parameter can be one of the following values: /// /// /// /// Value /// Meaning /// /// /// POWER_REQUEST_CONTEXT_DETAILED_STRING = 0x00000002 /// The Detailed structure identifies a localizable string resource that describes the reason for the power request. /// /// /// POWER_REQUEST_CONTEXT_SIMPLE_STRING = 0x00000001 /// /// The SimpleReasonString parameter contains a simple, non-localizable string that describes the reason for the power request. /// /// /// /// /// public DIAGNOSTIC_REASON Flags; private DETAIL _reason; /// A structure that identifies a localizable string resource to describe the reason for the power request. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct DETAIL { /// The module that contains the string resource. public IntPtr LocalizedReasonModule; /// The ID of the string resource. public uint LocalizedReasonId; /// The number of strings in the ReasonStrings parameter. public uint ReasonStringCount; /// An array of strings to be substituted in the string resource at run time. public IntPtr ReasonStrings; } /// Initializes a new instance of the class. /// The reason. public REASON_CONTEXT(string reason) { Version = DIAGNOSTIC_REASON_VERSION.DIAGNOSTIC_REASON_VERSION; Flags = DIAGNOSTIC_REASON.DIAGNOSTIC_REASON_SIMPLE_STRING; _reason.LocalizedReasonModule = Marshal.StringToHGlobalUni(reason); } /// Initializes a new instance of the class. /// The localized reason module. /// The reason identifier. /// The substituion values. public REASON_CONTEXT(HINSTANCE localizedReasonModule, uint reasonId, string[] substituionValues = null) { Version = DIAGNOSTIC_REASON_VERSION.DIAGNOSTIC_REASON_VERSION; Flags = DIAGNOSTIC_REASON.DIAGNOSTIC_REASON_DETAILED_STRING; _reason.LocalizedReasonModule = (IntPtr)localizedReasonModule; _reason.LocalizedReasonId = reasonId; _reason.ReasonStringCount = (uint)(substituionValues?.Length ?? 0); _reason.ReasonStrings = substituionValues?.MarshalToPtr(StringListPackMethod.Concatenated, Marshal.AllocHGlobal, out var _, CharSet.Unicode) ?? IntPtr.Zero; } void IDisposable.Dispose() { if (Flags == DIAGNOSTIC_REASON.DIAGNOSTIC_REASON_SIMPLE_STRING) Marshal.FreeHGlobal(_reason.LocalizedReasonModule); else if (Flags == DIAGNOSTIC_REASON.DIAGNOSTIC_REASON_DETAILED_STRING) Marshal.FreeHGlobal(_reason.ReasonStrings); } } /// A slim reader/writer (SRW) lock. [StructLayout(LayoutKind.Sequential)] public struct SRWLOCK { private readonly IntPtr ptr; } /// Provides a handle to a synchronization barrier. [StructLayout(LayoutKind.Sequential)] public struct SYNCHRONIZATION_BARRIER { private uint Reserved1; private uint Reserved2; private IntPtr Reserved3_1; private IntPtr Reserved3_2; private uint Reserved4; private uint Reserved5; } /// Provides a to an event that is automatically disposed using CloseHandle. public class SafeEventHandle : SafeSyncHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeEventHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } private SafeEventHandle() : base() { } /// Sets this event object to the nonsignaled state. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// public bool Reset() => ResetEvent(this); /// Sets this event object to the signaled state. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// public bool Set() => SetEvent(this); #pragma warning disable CS0618 // Type or member is obsolete /// Performs an implicit conversion from to . /// The SafeSyncHandle instance. /// The result of the conversion. public static implicit operator SafeEventHandle(EventWaitHandle h) => new SafeEventHandle(h.Handle, false); #pragma warning restore CS0618 // Type or member is obsolete /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator HEVENT(SafeEventHandle h) => h.handle; /// Gets an invalid event handle. public static SafeEventHandle InvalidHandle => new SafeEventHandle(new IntPtr(-1), false); /// Gets a null event handle. public static SafeEventHandle Null => new SafeEventHandle(IntPtr.Zero, false); /// Performs an explicit conversion from to . /// The event handle. /// The resulting instance from the conversion. public static explicit operator IntPtr(SafeEventHandle h) => h.handle; } /// Provides a to a mutex that is automatically disposed using CloseHandle. public class SafeMutexHandle : SafeSyncHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeMutexHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } private SafeMutexHandle() : base() { } /// Performs an implicit conversion from to . /// The SafeSyncHandle instance. /// The result of the conversion. public static implicit operator SafeMutexHandle(SafeWaitHandle h) => new SafeMutexHandle(h.DangerousGetHandle(), false); } /// /// Provides a to a wait handle created by RegisterWaitForSingleObject and closed on disposal by UnregisterWaitEx. /// public class SafeRegisteredWaitHandle : SafeHANDLE { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeRegisteredWaitHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } private SafeRegisteredWaitHandle() : base() { } /// /// Gets or sets the event object to be signaled when the wait operation has been unregistered. This property can be . /// /// The completion event. public SafeEventHandle CompletionEvent { get; set; } /// Gets or sets a value indicating whether the disposal waits for all callback functions to complete before returning. /// true if disposal wait for all functions to complete; otherwise, false. public bool WaitForAllFunctions { get; set; } /// Performs an implicit conversion from to . /// The handle pointer. /// The result of the conversion. public static implicit operator SafeRegisteredWaitHandle(IntPtr p) => new SafeRegisteredWaitHandle(p, false); /// protected override bool InternalReleaseHandle() { if (UnregisterWaitEx(handle, CompletionEvent ?? (WaitForAllFunctions ? SafeEventHandle.InvalidHandle : SafeEventHandle.Null))) return true; return CompletionEvent == null || Win32Error.GetLastError() != Win32Error.ERROR_IO_PENDING ? false : WaitForSingleObject(CompletionEvent, INFINITE) == WAIT_STATUS.WAIT_OBJECT_0; } } /// Provides a to a semaphore that is automatically disposed using CloseHandle. public class SafeSemaphoreHandle : SafeSyncHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeSemaphoreHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } private SafeSemaphoreHandle() : base() { } /// Performs an implicit conversion from to . /// The SafeSyncHandle instance. /// The result of the conversion. public static implicit operator SafeSemaphoreHandle(SafeWaitHandle h) => new SafeSemaphoreHandle(h.DangerousGetHandle(), false); } /// Provides a to a waitable timer that is automatically disposed using CloseHandle. public class SafeWaitableTimerHandle : SafeSyncHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeWaitableTimerHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } private SafeWaitableTimerHandle() : base() { } /// Performs an implicit conversion from to . /// The SafeSyncHandle instance. /// The result of the conversion. public static implicit operator SafeWaitableTimerHandle(SafeWaitHandle h) => new SafeWaitableTimerHandle(h.DangerousGetHandle(), false); } } }