code format

This commit is contained in:
2022-12-14 14:13:52 +03:00
parent 430a41fefc
commit c2b8a8d6da
297 changed files with 27331 additions and 24162 deletions

View File

@@ -1,24 +1,25 @@
/*
PIP - Platform Independent Primitives
Thread
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
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 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.
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 <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piincludes_p.h"
#include "pithread.h"
#include "piincludes_p.h"
#include "piintrospection_threads.h"
#include "pitime.h"
#ifndef MICRO_PIP
@@ -33,7 +34,7 @@
#elif defined(FREERTOS)
# define __THREAD_FUNC_RET__ void
#else
# define __THREAD_FUNC_RET__ void*
# define __THREAD_FUNC_RET__ void *
#endif
#ifndef FREERTOS
# define __THREAD_FUNC_END__ 0
@@ -47,11 +48,17 @@
#if defined(MAC_OS) || defined(BLACKBERRY)
# include <pthread.h>
#endif
__THREAD_FUNC_RET__ thread_function(void * t) {((PIThread*)t)->__thread_func__(); return __THREAD_FUNC_END__;}
__THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_func_once__(); return __THREAD_FUNC_END__;}
__THREAD_FUNC_RET__ thread_function(void * t) {
((PIThread *)t)->__thread_func__();
return __THREAD_FUNC_END__;
}
__THREAD_FUNC_RET__ thread_function_once(void * t) {
((PIThread *)t)->__thread_func_once__();
return __THREAD_FUNC_END__;
}
#ifndef MICRO_PIP
# define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
# define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
# define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
#else
# define REGISTER_THREAD(t)
@@ -449,15 +456,14 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_fun
#ifndef MICRO_PIP
__PIThreadCollection *__PIThreadCollection::instance() {
__PIThreadCollection * __PIThreadCollection::instance() {
return __PIThreadCollection_Initializer__::__instance__;
}
void __PIThreadCollection::registerThread(PIThread * t) {
lock();
if (!threads_.contains(t))
threads_ << t;
if (!threads_.contains(t)) threads_ << t;
unlock();
}
@@ -469,7 +475,7 @@ void __PIThreadCollection::unregisterThread(PIThread * t) {
}
PIVector<PIThread * > __PIThreadCollection::threads() const {
PIVector<PIThread *> __PIThreadCollection::threads() const {
return threads_;
}
@@ -490,26 +496,24 @@ void __PIThreadCollection::stoppedAuto() {
}
int __PIThreadCollection_Initializer__::count_(0);
__PIThreadCollection * __PIThreadCollection_Initializer__::__instance__(0);
__PIThreadCollection_Initializer__::__PIThreadCollection_Initializer__() {
count_++;
//PICout(PICoutManipulators::DefaultControls) << "try create Core" << count_;
// PICout(PICoutManipulators::DefaultControls) << "try create Core" << count_;
if (count_ > 1) return;
//PICout(PICoutManipulators::DefaultControls) << "create Core";
// PICout(PICoutManipulators::DefaultControls) << "create Core";
__instance__ = new __PIThreadCollection();
}
__PIThreadCollection_Initializer__::~__PIThreadCollection_Initializer__() {
count_--;
//PICout(PICoutManipulators::DefaultControls) << "try delete Core" << count_;
// PICout(PICoutManipulators::DefaultControls) << "try delete Core" << count_;
if (count_ > 0) return;
//PICout(PICoutManipulators::DefaultControls) << "delete Core";
// PICout(PICoutManipulators::DefaultControls) << "delete Core";
if (__instance__ != 0) {
delete __instance__;
__instance__ = 0;
@@ -533,38 +537,38 @@ PRIVATE_DEFINITION_END(PIThread)
PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() {
PIINTROSPECTION_THREAD_NEW(this);
tid_ = -1;
tid_ = -1;
PRIVATE->thread = 0;
data_ = data;
ret_func = func;
data_ = data;
ret_func = func;
terminating = running_ = lockRun = false;
priority_ = piNormal;
delay_ = timer_delay;
priority_ = piNormal;
delay_ = timer_delay;
if (startNow) start(timer_delay);
}
PIThread::PIThread(std::function<void ()> func, bool startNow, int timer_delay) {
PIThread::PIThread(std::function<void()> func, bool startNow, int timer_delay) {
PIINTROSPECTION_THREAD_NEW(this);
tid_ = -1;
tid_ = -1;
PRIVATE->thread = 0;
data_ = 0;
ret_func = [func](void*){func();};
data_ = 0;
ret_func = [func](void *) { func(); };
terminating = running_ = lockRun = false;
priority_ = piNormal;
delay_ = timer_delay;
priority_ = piNormal;
delay_ = timer_delay;
if (startNow) start(timer_delay);
}
PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
PIINTROSPECTION_THREAD_NEW(this);
tid_ = -1;
tid_ = -1;
PRIVATE->thread = 0;
ret_func = 0;
ret_func = 0;
terminating = running_ = lockRun = false;
priority_ = piNormal;
delay_ = timer_delay;
priority_ = piNormal;
delay_ = timer_delay;
if (startNow) start(timer_delay);
}
@@ -573,19 +577,19 @@ PIThread::~PIThread() {
PIINTROSPECTION_THREAD_DELETE(this);
if (!running_ || PRIVATE->thread == 0) return;
#ifdef FREERTOS
//void * ret(0);
//PICout(PICoutManipulators::DefaultControls) << "~PIThread" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << pthread_join(PRIVATE->thread, 0);
// void * ret(0);
// PICout(PICoutManipulators::DefaultControls) << "~PIThread" << PRIVATE->thread;
// PICout(PICoutManipulators::DefaultControls) << pthread_join(PRIVATE->thread, 0);
PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop";
stop(true);
//PICout(PICoutManipulators::DefaultControls) << "stopped!";
// PICout(PICoutManipulators::DefaultControls) << "stopped!";
#else
#ifndef WINDOWS
# ifdef ANDROID
# ifndef WINDOWS
# ifdef ANDROID
pthread_kill(PRIVATE->thread, SIGTERM);
# else
# else
pthread_cancel(PRIVATE->thread);
# endif
# endif
# else
TerminateThread(PRIVATE->thread, 0);
CloseHandle(PRIVATE->thread);
@@ -602,7 +606,7 @@ void PIThread::stopAndWait(int timeout_ms) {
void PIThread::stop() {
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop ..." << running_ << wait;
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop ..." << running_ << wait;
terminating = true;
}
@@ -610,46 +614,46 @@ void PIThread::stop() {
bool PIThread::start(int timer_delay) {
if (running_) return false;
delay_ = timer_delay;
return _startThread((void*)thread_function);
return _startThread((void *)thread_function);
}
bool PIThread::startOnce() {
if (running_) return false;
return _startThread((void*)thread_function_once);
return _startThread((void *)thread_function_once);
}
void PIThread::terminate() {
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ..." << running_;
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ..." << running_;
#ifdef FREERTOS
PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop";
stop(true);
//PICout(PICoutManipulators::DefaultControls) << "stopped!";
// PICout(PICoutManipulators::DefaultControls) << "stopped!";
#else
if (PRIVATE->thread == 0) return;
UNREGISTER_THREAD(this);
terminating = running_ = false;
tid_ = -1;
//PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
tid_ = -1;
// PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
# ifndef WINDOWS
# ifdef ANDROID
# ifdef ANDROID
pthread_kill(PRIVATE->thread, SIGTERM);
# else
//pthread_kill(PRIVATE->thread, SIGKILL);
//void * ret(0);
# else
// pthread_kill(PRIVATE->thread, SIGKILL);
// void * ret(0);
pthread_cancel(PRIVATE->thread);
//pthread_join(PRIVATE->thread, &ret);
# endif
// pthread_join(PRIVATE->thread, &ret);
# endif
# else
TerminateThread(PRIVATE->thread, 0);
CloseHandle(PRIVATE->thread);
# endif
PRIVATE->thread = 0;
end();
#endif //FREERTOS
#endif // FREERTOS
PIINTROSPECTION_THREAD_STOP(this);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
}
@@ -688,207 +692,206 @@ int PIThread::priority2System(PIThread::Priority p) {
bool PIThread::_startThread(void * func) {
terminating = false;
running_ = true;
running_ = true;
#if !defined(WINDOWS) && !defined(FREERTOS)
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&PRIVATE->thread, &attr, (__THREAD_FUNC_RET__(*)(void*))func, this);
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
int ret = pthread_create(&PRIVATE->thread, &attr, (__THREAD_FUNC_RET__(*)(void *))func, this);
// PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
pthread_attr_destroy(&attr);
if (ret == 0) {
# ifdef MAC_OS
pthread_setname_np(((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
pthread_setname_np(((PIString &)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
pthread_threadid_np(PRIVATE->thread, (__uint64_t *)&tid_);
# else
pthread_setname_np(PRIVATE->thread, ((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
pthread_setname_np(PRIVATE->thread, ((PIString &)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
# endif
#endif
#ifdef WINDOWS
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
# ifdef CC_GCC
PRIVATE->thread = (void *)_beginthreadex(0, 0, (__THREAD_FUNC_RET__(*)(void*))func, this, 0, 0);
PRIVATE->thread = (void *)_beginthreadex(0, 0, (__THREAD_FUNC_RET__(*)(void *))func, this, 0, 0);
# else
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
# endif
if (PRIVATE->thread != 0) {
if (PRIVATE->thread != 0) {
#endif
#ifdef FREERTOS
if (xTaskCreate(
(__THREAD_FUNC_RET__(*)(void*))func,
((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii(), // A name just for humans
128, // This stack size can be checked & adjusted by reading the Stack Highwater
this,
priority_,
&PRIVATE->thread
) == pdPASS) {
tid_ = (llong)PRIVATE->thread;
if (xTaskCreate((__THREAD_FUNC_RET__(*)(void *))func,
((PIString &)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii(), // A name just for humans
128, // This stack size can be checked & adjusted by reading the Stack Highwater
this,
priority_,
&PRIVATE->thread) == pdPASS) {
tid_ = (llong)PRIVATE->thread;
#endif
#ifndef FREERTOS
setPriority(priority_);
setPriority(priority_);
#endif
return true;
} else {
running_ = false;
PRIVATE->thread = 0;
piCoutObj << "Error: Can`t start new thread:" << errorString();
}
running_ = false;
return false;
}
return true;
} else {
running_ = false;
PRIVATE->thread = 0;
piCoutObj << "Error: Can`t start new thread:" << errorString();
}
running_ = false;
return false;
}
void PIThread::setPriority(PIThread::Priority prior) {
priority_ = prior;
if (!running_ || (PRIVATE->thread == 0)) return;
void PIThread::setPriority(PIThread::Priority prior) {
priority_ = prior;
if (!running_ || (PRIVATE->thread == 0)) return;
#ifdef FREERTOS
vTaskPrioritySet(PRIVATE->thread, priority2System(priority_));
vTaskPrioritySet(PRIVATE->thread, priority2System(priority_));
#else
# ifndef WINDOWS
//PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread;
// PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread;
policy_ = 0;
memset(&(PRIVATE->sparam), 0, sizeof(PRIVATE->sparam));
pthread_getschedparam(PRIVATE->thread, &policy_, &(PRIVATE->sparam));
PRIVATE->sparam.
# ifndef LINUX
sched_priority
# else
__sched_priority
# endif
= priority2System(priority_);
# ifndef LINUX
sched_priority
# else
__sched_priority
# endif
= priority2System(priority_);
pthread_setschedparam(PRIVATE->thread, policy_, &(PRIVATE->sparam));
# else
if (!running_ || (PRIVATE->thread == 0)) return;
SetThreadPriority(PRIVATE->thread, priority2System(priority_));
# endif
#endif //FREERTOS
}
#endif // FREERTOS
}
#ifdef WINDOWS
bool isExists(HANDLE hThread) {
//errorClear();
//piCout << "isExists" << hThread;
DWORD dw = 0;
GetExitCodeThread(hThread, &dw);
//piCout << ret << dw << errorString();
if (dw == STILL_ACTIVE) return true;
//piCout << errorString();
return false;
}
bool isExists(HANDLE hThread) {
// errorClear();
// piCout << "isExists" << hThread;
DWORD dw = 0;
GetExitCodeThread(hThread, &dw);
// piCout << ret << dw << errorString();
if (dw == STILL_ACTIVE) return true;
// piCout << errorString();
return false;
}
#endif
bool PIThread::waitForFinish(int timeout_msecs) {
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "PIThread::waitForFinish" << running_ << terminating << timeout_msecs;
if (!running_) return true;
if (timeout_msecs < 0) {
while (running_) {
piMinSleep();
bool PIThread::waitForFinish(int timeout_msecs) {
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "PIThread::waitForFinish" << running_ << terminating <<
// timeout_msecs;
if (!running_) return true;
if (timeout_msecs < 0) {
while (running_) {
piMinSleep();
#ifdef WINDOWS
if (!isExists(PRIVATE->thread)) {
unlock();
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
#endif
}
return true;
}
#endif
}
return true;
}
tmf_.reset();
while (running_ && tmf_.elapsed_m() < timeout_msecs) {
piMinSleep();
tmf_.reset();
while (running_ && tmf_.elapsed_m() < timeout_msecs) {
piMinSleep();
#ifdef WINDOWS
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
#endif
}
return tmf_.elapsed_m() < timeout_msecs;
}
}
return tmf_.elapsed_m() < timeout_msecs;
}
bool PIThread::waitForStart(int timeout_msecs) {
if (running_) return true;
if (timeout_msecs < 0) {
while (!running_)
piMinSleep();
return true;
}
tms_.reset();
while (!running_ && tms_.elapsed_m() < timeout_msecs)
piMinSleep();
return tms_.elapsed_m() < timeout_msecs;
}
bool PIThread::waitForStart(int timeout_msecs) {
if (running_) return true;
if (timeout_msecs < 0) {
while (!running_)
piMinSleep();
return true;
}
tms_.reset();
while (!running_ && tms_.elapsed_m() < timeout_msecs)
piMinSleep();
return tms_.elapsed_m() < timeout_msecs;
}
void PIThread::_beginThread() {
void PIThread::_beginThread() {
#ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
# endif
#endif
#ifdef WINDOWS
tid_ = GetCurrentThreadId();
tid_ = GetCurrentThreadId();
#endif
#ifdef LINUX
tid_ = gettid();
tid_ = gettid();
#endif
PIINTROSPECTION_THREAD_START(this);
REGISTER_THREAD(this);
running_ = true;
if (lockRun) thread_mutex.lock();
begin();
if (lockRun) thread_mutex.unlock();
started();
}
PIINTROSPECTION_THREAD_START(this);
REGISTER_THREAD(this);
running_ = true;
if (lockRun) thread_mutex.lock();
begin();
if (lockRun) thread_mutex.unlock();
started();
}
void PIThread::_runThread() {
PIINTROSPECTION_THREAD_RUN(this);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
if (lockRun) thread_mutex.lock();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
void PIThread::_runThread() {
PIINTROSPECTION_THREAD_RUN(this);
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
if (lockRun) thread_mutex.lock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
#ifdef PIP_INTROSPECTION
PITimeMeasurer _tm;
PITimeMeasurer _tm;
#endif
run();
run();
#ifdef PIP_INTROSPECTION
PIINTROSPECTION_THREAD_RUN_DONE(this, ullong(_tm.elapsed_u()));
PIINTROSPECTION_THREAD_RUN_DONE(this, ullong(_tm.elapsed_u()));
#endif
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "ok";
//printf("thread %p tick\n", this);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "...";
if (ret_func != 0) ret_func(data_);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "ok";
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "...";
if (lockRun) thread_mutex.unlock();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
}
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "ok";
// printf("thread %p tick\n", this);
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "...";
if (ret_func != 0) ret_func(data_);
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "ok";
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "...";
if (lockRun) thread_mutex.unlock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
}
void PIThread::_endThread() {
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
stopped();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) thread_mutex.lock();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
end();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) thread_mutex.unlock();
terminating = running_ = false;
tid_ = -1;
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
//cout << "thread " << t << " exiting ... " << endl;
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_THREAD_STOP(this);
void PIThread::_endThread() {
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
stopped();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) thread_mutex.lock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
end();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) thread_mutex.unlock();
terminating = running_ = false;
tid_ = -1;
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
// cout << "thread " << t << " exiting ... " << endl;
// PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_THREAD_STOP(this);
#if defined(WINDOWS)
# ifdef CC_GCC
_endthreadex(0);
_endthreadex(0);
# else
ExitThread(0);
ExitThread(0);
# endif
#elif defined(FREERTOS)
PRIVATE->thread = 0;
@@ -897,116 +900,115 @@ void PIThread::_endThread() {
PRIVATE->thread = 0;
pthread_exit(0);
#endif
}
void PIThread::__thread_func__() {
_beginThread();
while (!terminating) {
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "...";
maybeCallQueuedEvents();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "ok";
_runThread();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "...";
PIINTROSPECTION_THREAD_WAIT(this);
if (delay_ > 0) {
tmr_.reset();
double sl(0.);
while (1) {
sl = piMind(delay_ - tmr_.elapsed_m(), PIP_MIN_MSLEEP);
if (terminating) break;
if (sl <= 0.) break;
piMSleep(sl);
}
}
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "ok";
}
_endThread();
}
void PIThread::__thread_func_once__() {
_beginThread();
_runThread();
_endThread();
}
void PIThread::__thread_func__() {
_beginThread();
while (!terminating) {
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "...";
maybeCallQueuedEvents();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "ok";
_runThread();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "...";
PIINTROSPECTION_THREAD_WAIT(this);
if (delay_ > 0) {
tmr_.reset();
double sl(0.);
while (1) {
sl = piMind(delay_ - tmr_.elapsed_m(), PIP_MIN_MSLEEP);
if (terminating) break;
if (sl <= 0.) break;
piMSleep(sl);
}
}
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "ok";
}
_endThread();
}
//! \~\details
//! \~english
//! This method create %PIThread with name "name" and execute
//! event handler "handler" of object "object" in this thread.\n
//! This %PIThread automatically delete on function finish.
//!
//! \~russian
//! Этот метод создает %PIThread с именем "name" и выполняет
//! обработчик "handler" объекта "object" в этом потоке.\n
//! %PIThread автоматически удаляется после завершения обработчика.
//!
//! \~\code
//! class MyObj: public PIObject {
//! PIOBJECT(MyObj)
//! public:
//! EVENT_HANDLER(void, threadRun) {
//! piForTimes (5) {
//! piCout << "threadRun";
//! piMSleep(100);
//! }
//! };
//! };
//!
//! int main(int argc, char * argv[]) {
//! MyObj mo;
//! PIThread::runOnce(&mo, "threadRun");
//! piMSleep(1000); // wait for thread finish
//! return 0;
//! }
//! \endcode
void PIThread::runOnce(PIObject * object, const char * handler, const PIString & name) {
PIThread * t = new PIThread();
t->setName(name);
if (!PIObject::piConnectU(t, PIStringAscii("started"), object, object, PIStringAscii(handler), "PIThread::runOnce").isValid()) {
delete t;
return;
}
void PIThread::__thread_func_once__() {
_beginThread();
_runThread();
_endThread();
}
//! \~\details
//! \~english
//! This method create %PIThread with name "name" and execute
//! event handler "handler" of object "object" in this thread.\n
//! This %PIThread automatically delete on function finish.
//!
//! \~russian
//! Этот метод создает %PIThread с именем "name" и выполняет
//! обработчик "handler" объекта "object" в этом потоке.\n
//! %PIThread автоматически удаляется после завершения обработчика.
//!
//! \~\code
//! class MyObj: public PIObject {
//! PIOBJECT(MyObj)
//! public:
//! EVENT_HANDLER(void, threadRun) {
//! piForTimes (5) {
//! piCout << "threadRun";
//! piMSleep(100);
//! }
//! };
//! };
//!
//! int main(int argc, char * argv[]) {
//! MyObj mo;
//! PIThread::runOnce(&mo, "threadRun");
//! piMSleep(1000); // wait for thread finish
//! return 0;
//! }
//! \endcode
void PIThread::runOnce(PIObject * object, const char * handler, const PIString & name) {
PIThread * t = new PIThread();
t->setName(name);
if (!PIObject::piConnectU(t, PIStringAscii("started"), object, object, PIStringAscii(handler), "PIThread::runOnce").isValid()) {
delete t;
return;
}
#ifndef MICRO_PIP
__PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
__PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
#endif
t->startOnce();
}
t->startOnce();
}
//! \~\details
//! \~english
//! This method create %PIThread with name "name" and execute
//! [lambda expression](https://en.cppreference.com/w/cpp/language/lambda) "func" in this thread.\n
//! This %PIThread automatically delete on function finish.\n
//! "func" shouldn`t have arguments.
//!
//! \~russian
//! Этот метод создает %PIThread с именем "name" и выполняет
//! [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda) "func" в этом потоке.\n
//! %PIThread автоматически удаляется после завершения функции.\n
//! "func" не должна иметь аргументов.
//!
//! \~\code
//! PIThread::runOnce([](){
//! piForTimes(5) {
//! piCout << "thread func";
//! piMSleep(100);
//! }
//! });
//! piMSleep(1000);
//! \endcode
void PIThread::runOnce(std::function<void ()> func, const PIString & name) {
PIThread * t = new PIThread();
t->setName(name);
t->setSlot(func);
//! \~\details
//! \~english
//! This method create %PIThread with name "name" and execute
//! [lambda expression](https://en.cppreference.com/w/cpp/language/lambda) "func" in this thread.\n
//! This %PIThread automatically delete on function finish.\n
//! "func" shouldn`t have arguments.
//!
//! \~russian
//! Этот метод создает %PIThread с именем "name" и выполняет
//! [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda) "func" в этом потоке.\n
//! %PIThread автоматически удаляется после завершения функции.\n
//! "func" не должна иметь аргументов.
//!
//! \~\code
//! PIThread::runOnce([](){
//! piForTimes(5) {
//! piCout << "thread func";
//! piMSleep(100);
//! }
//! });
//! piMSleep(1000);
//! \endcode
void PIThread::runOnce(std::function<void()> func, const PIString & name) {
PIThread * t = new PIThread();
t->setName(name);
t->setSlot(func);
#ifndef MICRO_PIP
__PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
__PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
#endif
t->startOnce();
}
t->startOnce();
}