/* * Copyright (c) Likewise Software. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. You should have received a copy of the GNU General * Public License along with this program. If not, see * . * * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU * GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT * license@likewise.com */ /* * Copyright (C) Likewise Software. All rights reserved. * * Module Name: * * threads.h * * Abstract: * * Likewise Base * * Thread Utilities * * Authors: Danilo Almeida (dalmeida@likewise.com) */ #ifndef __LW_BASE_THREADS_H__ #define __LW_BASE_THREADS_H__ #include #include #include // Unix time_t is seconds since January 1, 1970. Negative values // are times before then. typedef LONG64 LW_RTL_UNIX_TIME_SECONDS, *PLW_RTL_UNIX_TIME_SECONDS; // Similar to WDK, where positive time is absolute time in 100ns since // January 1, 1601 AD. // // Note that maximum time is therefore until around the year // 30,000 AD. // // Negative time can vary in meaning. In some APIs, negative is disallowed // (or sometimes -1 is special). In others, it is relative time in 100ns // increments. typedef LONG64 LW_RTL_WINDOWS_TIME, *PLW_RTL_WINDOWS_TIME; #define LW_RTL_WINDOWS_TIMESPAN_MICROSECOND ((LW_RTL_WINDOWS_TIME) 10) #define LW_RTL_WINDOWS_TIMESPAN_MILLISECOND ((LW_RTL_WINDOWS_TIME) 1000 * LW_RTL_WINDOWS_TIMESPAN_MICROSECOND) #define LW_RTL_WINDOWS_TIMESPAN_SECOND ((LW_RTL_WINDOWS_TIME) 1000 * LW_RTL_WINDOWS_TIMESPAN_MILLISECOND) #define LW_RTL_WINDOWS_TIMESPAN_MINUTE ((LW_RTL_WINDOWS_TIME) 60 * LW_RTL_WINDOWS_TIMESPAN_SECOND) #define LW_RTL_WINDOWS_TIMESPAN_HOUR ((LW_RTL_WINDOWS_TIME) 60 * LW_RTL_WINDOWS_TIMESPAN_MINUTE) #define LW_RTL_WINDOWS_TIMESPAN_DAY ((LW_RTL_WINDOWS_TIME) 24 * LW_RTL_WINDOWS_TIMESPAN_HOUR) NTSTATUS LwRtlGetCurrentWindowsTime( OUT PLW_RTL_WINDOWS_TIME WindowsTime ); // Opaque, except that zero-memory init means uninitialized... // and cleanup is always safe on uninitialized. typedef LW_ULONG _LW_RTL_EVENT_FLAGS; typedef struct _LW_RTL_EVENT { struct { _LW_RTL_EVENT_FLAGS Flags; pthread_cond_t Condition; pthread_mutex_t Mutex; } Private; } LW_RTL_EVENT, *PLW_RTL_EVENT; #define LW_RTL_EVENT_ZERO_INITIALIZER { { 0 } } // TODO: Add IsManualReset LW_NTSTATUS LwRtlInitializeEvent( OUT PLW_RTL_EVENT pEvent ); LW_VOID LwRtlCleanupEvent( IN OUT PLW_RTL_EVENT pEvent ); LW_BOOLEAN LwRtlWaitEvent( IN PLW_RTL_EVENT pEvent, IN OPTIONAL PLW_RTL_WINDOWS_TIME Timeout ); LW_VOID LwRtlSetEvent( IN PLW_RTL_EVENT pEvent ); typedef LW_ULONG _LW_RTL_MUTEX_FLAGS; typedef struct _LW_RTL_MUTEX { struct { _LW_RTL_MUTEX_FLAGS Flags; pthread_mutex_t Mutex; } Private; } LW_RTL_MUTEX, *PLW_RTL_MUTEX; #define LW_RTL_MUTEX_ZERO_INITIALIZER { { 0 } } LW_NTSTATUS LwRtlInitializeMutex( OUT PLW_RTL_MUTEX pMutex, IN BOOLEAN IsRecursive ); LW_VOID LwRtlCleanupMutex( IN OUT PLW_RTL_MUTEX pMutex ); LW_BOOLEAN LwRtlTryLockMutex( IN PLW_RTL_MUTEX pMutex ); LW_VOID LwRtlLockMutex( IN PLW_RTL_MUTEX pMutex ); LW_VOID LwRtlUnlockMutex( IN PLW_RTL_MUTEX pMutex ); typedef LW_ULONG _LW_RTL_CONDITION_VARIABLE_FLAGS; typedef struct _LW_RTL_CONDITION_VARIABLE { struct { _LW_RTL_CONDITION_VARIABLE_FLAGS Flags; pthread_cond_t Condition; } Private; } LW_RTL_CONDITION_VARIABLE, *PLW_RTL_CONDITION_VARIABLE; #define LW_RTL_CONDITION_VARIABLE_ZERO_INITIALIZER { { 0 } } LW_NTSTATUS LwRtlInitializeConditionVariable( OUT PLW_RTL_CONDITION_VARIABLE pConditionVariable ); LW_VOID LwRtlCleanupConditionVariable( IN OUT PLW_RTL_CONDITION_VARIABLE pConditionVariable ); LW_BOOLEAN LwRtlWaitConditionVariable( IN PLW_RTL_CONDITION_VARIABLE pConditionVariable, IN PLW_RTL_MUTEX pMutex, IN OPTIONAL PLW_RTL_WINDOWS_TIME Timeout ); LW_VOID LwRtlSignalConditionVariable( IN PLW_RTL_CONDITION_VARIABLE pConditionVariable ); LW_VOID LwRtlBroadcastConditionVariable( IN PLW_RTL_CONDITION_VARIABLE pConditionVariable ); struct _LW_RTL_THREAD; typedef struct _LW_RTL_THREAD *PLW_RTL_THREAD; typedef LW_PVOID (*LW_THREAD_PROC)(LW_PVOID ThreadContext); LW_NTSTATUS LwRtlCreateThread( OUT PLW_RTL_THREAD* ppThread, IN LW_THREAD_PROC ThreadRoutine, IN LW_PVOID ThreadContext ); LW_PVOID LwRtlJoinThread( IN OUT PLW_RTL_THREAD pThread ); LW_VOID LwRtlDetachThread( IN OUT PLW_RTL_THREAD pThread ); #if 0 typedef struct _LW_RTL_THREAD { BOOLEAN IsInitialized; pthread_t Internal; } LW_RTL_THREAD, *PLW_RTL_THREAD; typedef struct _LW_RTL_MUTEX { BOOLEAN IsInitialized; pthread_mutex_t Internal; } LW_RTL_MUTEX, *PLW_RTL_MUTEX; typedef struct _LW_RTL_RWLOCK { BOOLEAN IsInitialized; pthread_rwlock_t Internal; } LW_RTL_RWLOCK, *PLW_RTL_RWLOCK; // Similar to WDK, negative is relative time and positive // is abosolute time in 100ns since January 1, 1601. typedef LONG64 LW_RTL_WINDOWS_TIME, *PW_RTL_WINDOWS_TIME; #define LW_RTL_WINDOWS_TIMESPAN_MICROSECOND 10 #define LW_RTL_WINDOWS_TIMESPAN_MILLISECOND (1000 * LW_RTL_WINDOWS_TIMESPAN_MICROSECOND) #define LW_RTL_WINDOWS_TIMESPAN_SECOND (1000 * LW_RTL_WINDOWS_TIMESPAN_MILLISECOND) #define LW_RTL_WINDOWS_TIMESPAN_MINUTE (60 * LW_RTL_WINDOWS_TIMESPAN_SECOND) #define LW_RTL_WINDOWS_TIMESPAN_HOUR (60 * LW_RTL_WINDOWS_TIMESPAN_MINUTE) #define LW_RTL_WINDOWS_TIMESPAN_DAY (24 * LW_RTL_WINDOWS_TIMESPAN_HOUR) BOOLEAN LwRtlWaitTimeoutEvent( IN PLW_RTL_EVENT pEvent, IN PLW_RTL_MUTEX pMutex, IN LW_RTL_WINDOWS_TIMESPAN Timeout ); BOOLEAN LwRtlWaitAbsoluteTimeEvent( IN PLW_RTL_EVENT pEvent, IN PLW_RTL_MUTEX pMutex, IN LW_RTL_WINDOWS_TIME Time ); VOID LwRtlSignalEvent( IN PLW_RTL_EVENT pEvent ); VOID LwRtlBroadcastEvent( IN PLW_RTL_EVENT pEvent ); #endif ///////////////////////////////// NTSTATUS LwRtlThreadsCreateThread( OUT pthread_t** ppThread, IN PVOID (*ThreadRoutine)(PVOID), IN PVOID ThreadContext ); NTSTATUS LwRtlThreadsCreateDetachedThread( IN PVOID (*ThreadRoutine)(PVOID), IN PVOID ThreadContext ); typedef UCHAR LW_RTL_THREADS_MUTEX_TYPE; #define LW_RTL_THREADS_MUTEX_TYPE_RECURSIVE 1 NTSTATUS LwRtlThreadsCreateMutex( OUT pthread_mutex_t** ppMutex, IN LW_RTL_THREADS_MUTEX_TYPE MutexType ); VOID LwRtlThreadsDestroyMutex( IN OUT pthread_mutex_t** ppMutex ); NTSTATUS LwRtlThreadsInitializeMutex( OUT pthread_mutex_t* pMutex, IN LW_RTL_THREADS_MUTEX_TYPE MutexType ); VOID LwRtlThreadsCleanupMutex( IN OUT pthread_mutex_t* pMutex ); VOID LwThreadsAcquireMutex( IN pthread_mutex_t* pMutex ); VOID LwThreadsReleaseMutex( IN pthread_mutex_t* pMutex ); NTSTATUS LwRtlThreadsCreateCond( OUT pthread_cond_t** ppCond ); VOID LwRtlThreadsDestroyCond( IN OUT pthread_cond_t** ppCond ); #endif /* __LW_BASE_THREADS_H__ */