#pragma once /** * @RDE_HEADER@ * Thread management for generic FTCs * $Id: generic_ftc_impl.h 62388 2024-03-27 10:41:26Z wille_m $ * $HeadURL: svn://slssvn/TDS/branches/product/features/swp_2023_devel/Lts/DDS/FTC/generic_ftc_impl.h $ * $Author: wille_m $ * * Created by Mike Wille, ESZS, 27-03-2024 */ #include #include #include #include #include #include class CancelationPointReached : public std::runtime_error { public: //using std::runtime_error::runtime_error; explicit CancelationPointReached() : std::runtime_error("CancelationPointReached") {} }; class Threading // : public QObject { //Q_OBJECT public: Threading() = default; ~Threading(); protected: void preInit() const; // managing thread: void createThread(); // creates a thread if not already running - run before adding requests void runThread(); // notify thread // m_conditionMutex inline bool isRun() const { return (m_run != 0); } inline void setRun(bool run) { m_run = (run ? 1 : 0); } // m_conditionMutex inline void setWorkAvailable(bool workAvailable) { m_workAvailable = (workAvailable ? 1 : 0); } inline bool isWorkAvailable() const { return (m_workAvailable != 0); } // m_conditionMutex inline void setWorking(bool working) { m_isWorking = (working ? 1 : 0); } inline bool isWorking() const { return (m_isWorking != 0); } const QString &threadName() const; inline const char *posixThreadName() const; virtual void work() = 0; virtual QString functionTopicName() const = 0; virtual int partitionId() const = 0; virtual QString partitionType() const = 0; virtual void cleanupThread() = 0; // in-thread! virtual void threadDone() = 0; inline void cancellationPoint() const noexcept(false) // in-thread { if (!isRun()) { // fprintf(stderr, "Threading: cancelation point reached\n"); throw CancelationPointReached(); } } std::mutex m_conditionMutex; private: inline bool isCleanupNeeded() const { return (m_cleanupNeeded != 0); } inline void setCleanupNeeded(bool cleanupNeeded) { m_cleanupNeeded = (cleanupNeeded ? 1 : 0); } void run(const QString &threadName); // in-thread //void stop(); std::unique_ptr m_threadLifetime; QAtomicInt m_run { 0 }; QAtomicInt m_cleanupNeeded { 1 }; std::thread m_thread; // invalid / not a thread std::condition_variable m_condition; QAtomicInt m_workAvailable { 0 }; QAtomicInt m_isWorking { 0 }; mutable QString m_threadName; mutable std::string m_posixThreadName; QAtomicInt m_alreadyThreaded; mutable int m_partitionId { -1 }; mutable QString m_partitionType; bool m_used { false }; bool m_createThreadCalledBefore { false }; };