code format
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user