// SPDX-License-Identifier: GPL-2.0-only /* * Digital Voice Modem - Common Library * GPLv2 Open Source. Use is subject to license terms. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright (C) 2015,2016 Jonathan Naylor, G4KLX * Copyright (C) 2023,2024 Bryan Biedenkapp, N2PLL * */ /** * @defgroup threading Threading * @brief Defines and implements threading routines. * @ingroup common * * @file Thread.h * @ingroup threading * @file Thread.cpp * @ingroup threading */ #if !defined(__THREAD_H__) #define __THREAD_H__ #include "common/Defines.h" #include #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include #else #include #endif // defined(_WIN32) #if defined(_WIN32) /* Thread identifiers. The structure of the attribute type is not exposed on purpose. */ typedef HANDLE pthread_t; #endif // defined(_WIN32) // --------------------------------------------------------------------------- // Structure Declaration // --------------------------------------------------------------------------- /** * @brief Represents the data passed to a thread runner. * @ingroup common */ struct thread_t { void* obj; //!< Object that created this thread. pthread_t thread; //!< Thread Handle. }; // --------------------------------------------------------------------------- // Class Declaration // --------------------------------------------------------------------------- /** * @brief Creates and controls a thread. * @ingroup threading */ class HOST_SW_API Thread { public: /** * @brief Initializes a new instance of the Thread class. */ Thread(); /** * @brief Finalizes a instance of the Thread class. */ virtual ~Thread(); /** * @brief Starts the thread execution. * @returns bool True, if thread started, otherwise false. */ virtual bool run(); /** * @brief User-defined function to run for the thread main. */ virtual void entry() = 0; /** * @brief Make calling thread wait for termination of the thread. */ virtual void wait(); /** * @brief Set thread name visible in the kernel and its interfaces. * @param name Textual name for thread. */ virtual void setName(std::string name); /** * @brief The resources of thread will therefore be freed immediately when it * terminates, instead of waiting for another thread to perform wait() */ virtual void detach(); /** * @brief Executes the specified start routine to run as a thread. * On POSIX, if the thread fails to spawn for any reason, the caller should clean up the passed thread_t * argument. This shouldn't be used for spawning threads used for things like packet processing. * @param obj Instance of a object to pass to the threaded function. * @param startRoutine Represents the function that executes on a thread. * @param[out] thread Instance of the thread data. * @returns bool True, if successful, otherwise error occurred. */ static bool runAsThread(void* obj, void *(*startRoutine)(void *), thread_t* thread = nullptr); /** * @brief Suspends the current thread for the specified amount of time. * @param ms Time in milliseconds to sleep. * @param us Time in microseconds to sleep. */ static void sleep(uint32_t ms, uint32_t us = 0U); private: pthread_t m_thread; /** * @brief Internal helper thats used as the entry point for the thread. * @param arg * @returns void* */ #if defined(_WIN32) static DWORD __stdcall helper(LPVOID arg); #else static void* helper(void* arg); #endif // defined(_WIN32) public: /** * @brief Flag indicating if the thread was started. */ DECLARE_PROTECTED_RO_PROPERTY_PLAIN(bool, started); }; #endif // __THREAD_H__