/*! \file pithread.h * \ingroup Thread * \~\brief * \~english Thread class * \~russian Класс потока */ /* PIP - Platform Independent Primitives Thread Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PITHREAD_H #define PITHREAD_H #include "piinit.h" #include "pimutex.h" #include "piobject.h" class PIThread; #ifndef MICRO_PIP class PIIntrospectionThreads; class PIP_EXPORT __PIThreadCollection: public PIObject { PIOBJECT(__PIThreadCollection) public: static __PIThreadCollection * instance(); void registerThread(PIThread * t); void unregisterThread(PIThread * t); PIVector threads() const; void lock() {mutex.lock();} void unlock() {mutex.unlock();} void startedAuto(PIThread * t); EVENT_HANDLER(void, stoppedAuto); private: PIVector threads_, auto_threads_; mutable PIMutex mutex, auto_mutex; }; class PIP_EXPORT __PIThreadCollection_Initializer__ { public: __PIThreadCollection_Initializer__(); ~__PIThreadCollection_Initializer__(); static int count_; static __PIThreadCollection * __instance__; }; static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__; #endif // MICRO_PIP typedef std::function ThreadFunc; class PIP_EXPORT PIThread: public PIObject { PIOBJECT_SUBCLASS(PIThread, PIObject) #ifndef MICRO_PIP friend class PIIntrospectionThreads; #endif public: NO_COPY_CLASS(PIThread) //! \~english Contructs thread with custom data "data", external function "func" and main loop delay "loop_delay" //! \~russian Создает поток с данными "data", функцией "func" и задержкой цикла "loop_delay" PIThread(void * data, ThreadFunc func, bool startNow = false, int loop_delay = -1); //! \~english Contructs thread with external function "func" and main loop delay "loop_delay" //! \~russian Создает поток с функцией "func" и задержкой цикла "loop_delay" PIThread(std::function func, bool startNow = false, int loop_delay = -1); //! \~english Contructs thread with main loop delay "loop_delay" //! \~russian Создает поток с задержкой цикла "loop_delay" PIThread(bool startNow = false, int loop_delay = -1); virtual ~PIThread(); //! \~english Priority of thread //! \~russian Приоритет потока enum Priority { piLowerst /** \~english Lowest \~russian Низший */ , piLow /** \~english Low \~russian Низкий */ , piNormal /** \~english Normal, this is default priority of threads and timers \~russian Нормальный, это приоритет по умолчанию для потоков и таймеров */ , piHigh /** \~english High \~russian Высокий */ , piHighest /** \~english Highest \~russian Высший */ }; EVENT_HANDLER0(bool, start) {return start(-1);} EVENT_HANDLER1(bool, start, int, timer_delay); bool start(ThreadFunc func) {return start(func, -1);} bool start(ThreadFunc func, int timer_delay) {ret_func = func; return start(timer_delay);} bool start(std::function func) {return start(func, -1);} bool start(std::function func, int timer_delay) {ret_func = [func](void*){func();}; return start(timer_delay);} EVENT_HANDLER0(bool, startOnce); EVENT_HANDLER1(bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();} EVENT_HANDLER0(void, stop) {stop(false);} EVENT_HANDLER1(void, stop, bool, wait); EVENT_HANDLER0(void, terminate); //! \~english Set common data passed to external function //! \~russian Устанавливает данные, передаваемые в функцию потока void setData(void * d) {data_ = d;} //! \~english Set external function that will be executed after every \a run() //! \~russian Устанавливает функцию потока, вызываемую после каждого \a run() void setSlot(ThreadFunc func) {ret_func = func;} //! \~english Set external function that will be executed after every \a run() //! \~russian Устанавливает функцию потока, вызываемую после каждого \a run() void setSlot(std::function func) {ret_func = [func](void*){func();};} //! \~english Set thread priority //! \~russian Устанавливает приоритет потока void setPriority(PIThread::Priority prior); //! \~english Returns common data passed to external function //! \~russian Возвращает данные, передаваемые в функцию потока void * data() const {return data_;} //! \~english Return thread priority //! \~russian Возвращает приоритет потока PIThread::Priority priority() const {return priority_;} //! \~english Return if thread is running //! \~russian Возвращает исполняется ли поток bool isRunning() const {return running_;} //! \~english Return if thread is stopping //! \~russian Возвращает останавливается ли поток bool isStopping() const {return running_ && terminating;} EVENT_HANDLER0(bool, waitForStart) {return waitForStart(-1);} EVENT_HANDLER1(bool, waitForStart, int, timeout_msecs); EVENT_HANDLER0(bool, waitForFinish) {return waitForFinish(-1);} EVENT_HANDLER1(bool, waitForFinish, int, timeout_msecs); //! \~english Set necessity of lock every \a run() with internal mutex //! \~russian Устанавливает необходимость блокировки внутреннего мьютекса каждый \a run() void needLockRun(bool need) {lockRun = need;} EVENT_HANDLER0(void, lock) const {thread_mutex.lock();} EVENT_HANDLER0(void, unlock) const {thread_mutex.unlock();} //! \~english Returns internal mutex //! \~russian Возвращает внутренний мьютекс PIMutex & mutex() const {return thread_mutex;} //! \~english Returns thread ID //! \~russian Возвращает ID потока llong tid() const {return tid_;} void __thread_func__(); void __thread_func_once__(); EVENT(started) EVENT(stopped) //! \~english Call event handler "handler" of object "object" in separate thread //! \~russian Вызывает обработчик "handler" объекта "object" в отдельном потоке static void runOnce(PIObject * object, const char * handler, const PIString & name = PIString()); //! \~english Call lambda-function "func" in separate thread //! \~russian Вызывает лямбда-функцию "func" в отдельном потоке static void runOnce(std::function func, const PIString & name = PIString()); //! \handlers //! \{ //! \fn bool start(int timer_delay = -1) //! \~english Start thread //! \~russian Запускает поток //! \fn bool startOnce() //! \~english Start thread without internal loop //! \~russian Запускает поток без внутреннего цикла //! \fn bool startOnce(ThreadFunc func) //! \~english Start thread without internal loop //! \~russian Запускает поток без внутреннего цикла //! \fn void stop(bool wait = false) //! \~english Stop thread //! \~russian Останавливает поток //! \fn void terminate() //! \~english Strongly stop thread //! \~russian Жестко останавливает поток //! \fn bool waitForStart(int timeout_msecs = -1) //! \~english Wait for thread start //! \~russian Ожидает старта потока //! \fn bool waitForFinish(int timeout_msecs = -1) //! \~english Wait for thread finish //! \~russian Ожидает завершения потока //! \fn void lock() //! \~english Lock internal mutex //! \~russian Блокирует внутренний мьютекс //! \fn void unlock() //! \~english Unlock internal mutex //! \~russian Разблокирует внутренний мьютекс //! \} //! \events //! \{ //! \fn void started() //! \~english Raise on thread start //! \~russian Вызывается при старте потока //! \fn void stopped() //! \~english Raise on thread stop //! \~russian Вызывается при завершении потока //! \} protected: static int priority2System(PIThread::Priority p); //! \~english Function executed once at the start of thread //! \~russian Метод выполняется один раз при старте потока virtual void begin() {;} //! \~english Function executed at every "timer_delay" msecs until thread was stopped //! \~russian Метод выполняется каждые "timer_delay" миллисекунд virtual void run() {;} //! \~english Function executed once at the end of thread //! \~russian Метод выполняется один раз при остановке потока virtual void end() {;} std::atomic_bool terminating, running_, lockRun; int delay_, policy_; llong tid_; void * data_; mutable PIMutex thread_mutex; PITimeMeasurer tmf_, tms_, tmr_; PIThread::Priority priority_; ThreadFunc ret_func; PRIVATE_DECLARATION(PIP_EXPORT) private: bool _startThread(void * func); void _beginThread(); void _runThread(); void _endThread(); }; #endif // PITHREAD_H