/* * mptThread.h * ----------- * Purpose: Helper class for running threads, with a more or less platform-independent interface. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "BuildSettings.h" #if defined(MPT_ENABLE_THREAD) #include #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS #include #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER #endif // MPT_ENABLE_THREAD OPENMPT_NAMESPACE_BEGIN #if defined(MPT_ENABLE_THREAD) namespace mpt { #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS && (MPT_COMPILER_MSVC || MPT_COMPILER_CLANG) enum ThreadPriority { ThreadPriorityLowest = THREAD_PRIORITY_LOWEST, ThreadPriorityLower = THREAD_PRIORITY_BELOW_NORMAL, ThreadPriorityNormal = THREAD_PRIORITY_NORMAL, ThreadPriorityHigh = THREAD_PRIORITY_ABOVE_NORMAL, ThreadPriorityHighest = THREAD_PRIORITY_HIGHEST }; inline void SetThreadPriority(std::thread &t, mpt::ThreadPriority priority) { ::SetThreadPriority(t.native_handle(), priority); } inline void SetCurrentThreadPriority(mpt::ThreadPriority priority) { ::SetThreadPriority(GetCurrentThread(), priority); } #else // !MPT_OS_WINDOWS enum ThreadPriority { ThreadPriorityLowest = -2, ThreadPriorityLower = -1, ThreadPriorityNormal = 0, ThreadPriorityHigh = 1, ThreadPriorityHighest = 2 }; inline void SetThreadPriority(std::thread & /*t*/ , mpt::ThreadPriority /*priority*/ ) { // nothing } inline void SetCurrentThreadPriority(mpt::ThreadPriority /*priority*/ ) { // nothing } #endif // MPT_OS_WINDOWS && (MPT_COMPILER_MSVC || MPT_COMPILER_CLANG) #endif // MODPLUG_TRACKER #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS // Default WinAPI thread class UnmanagedThread { protected: HANDLE threadHandle; public: operator HANDLE& () { return threadHandle; } operator bool () const { return threadHandle != nullptr; } UnmanagedThread() : threadHandle(nullptr) { } UnmanagedThread(LPTHREAD_START_ROUTINE function, void *userData = nullptr) { DWORD dummy = 0; // For Win9x threadHandle = CreateThread(NULL, 0, function, userData, 0, &dummy); } UnmanagedThread(UnmanagedThread &&) = default; UnmanagedThread & operator=(UnmanagedThread &&) = default; UnmanagedThread(const UnmanagedThread &) = delete; UnmanagedThread & operator=(const UnmanagedThread &) = delete; // unmanaged, user has to free resources ~UnmanagedThread() { } }; // Thread that operates on a member function template class UnmanagedThreadMember : public mpt::UnmanagedThread { protected: static DWORD WINAPI wrapperFunc(LPVOID param) { (static_cast(param)->*Fun)(); return 0; } public: UnmanagedThreadMember(T *instance) : mpt::UnmanagedThread(wrapperFunc, instance) { } }; inline void SetThreadPriority(mpt::UnmanagedThread &t, mpt::ThreadPriority priority) { ::SetThreadPriority(t, priority); } #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER } // namespace mpt #endif // MPT_ENABLE_THREAD OPENMPT_NAMESPACE_END