git-svn-id: svn://db.shs.com.ru/pip@756 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2019-02-18 18:30:51 +00:00
parent 0af7eabf56
commit 217947cc89
16 changed files with 296 additions and 217 deletions

View File

@@ -34,8 +34,8 @@
#if defined(MAC_OS) || defined(BLACKBERRY) || defined(FREERTOS)
# include <pthread.h>
#endif
__THREAD_FUNC_RET__ thread_function(void * t) {PIThread::__thread_func__(t); return 0;}
__THREAD_FUNC_RET__ thread_function_once(void * t) {PIThread::__thread_func_once__(t); return 0;}
__THREAD_FUNC_RET__ thread_function(void * t) {((PIThread*)t)->__thread_func__(); return 0;}
__THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_func_once__(); return 0;}
#define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
#define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
@@ -128,18 +128,18 @@ __PIThreadCollection * __PIThreadCollection_Initializer__::__instance__(0);
__PIThreadCollection_Initializer__::__PIThreadCollection_Initializer__() {
count_++;
//piCout << "try create Core" << count_;
//PICout(PICoutManipulators::DefaultControls) << "try create Core" << count_;
if (count_ > 1) return;
//piCout << "create Core";
//PICout(PICoutManipulators::DefaultControls) << "create Core";
__instance__ = new __PIThreadCollection();
}
__PIThreadCollection_Initializer__::~__PIThreadCollection_Initializer__() {
count_--;
//piCout << "try delete Core" << count_;
//PICout(PICoutManipulators::DefaultControls) << "try delete Core" << count_;
if (count_ > 0) return;
//piCout << "delete Core";
//PICout(PICoutManipulators::DefaultControls) << "delete Core";
if (__instance__ != 0) {
delete __instance__;
__instance__ = 0;
@@ -168,7 +168,6 @@ PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay)
terminating = running_ = lockRun = false;
priority_ = piNormal;
delay_ = timer_delay;
piCout << "PIThread" << this;
if (startNow) start(timer_delay);
}
@@ -181,7 +180,6 @@ PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
terminating = running_ = lockRun = false;
priority_ = piNormal;
delay_ = timer_delay;
piCout << "PIThread" << this;
if (startNow) start(timer_delay);
}
@@ -191,11 +189,11 @@ PIThread::~PIThread() {
if (!running_ || PRIVATE->thread == 0) return;
#ifdef FREERTOS
//void * ret(0);
//piCout << "~PIThread" << PRIVATE->thread;
//piCout << pthread_join(PRIVATE->thread, 0);
piCout << "FreeRTOS can't terminate pthreads! waiting for stop";
//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 << "stopped!";
//PICout(PICoutManipulators::DefaultControls) << "stopped!";
#else
#ifndef WINDOWS
# ifdef ANDROID
@@ -204,8 +202,6 @@ PIThread::~PIThread() {
pthread_cancel(PRIVATE->thread);
# endif
# else
piCout << "terminate by ~PIThread" << this;
while(1) msleep(10);
TerminateThread(PRIVATE->thread, 0);
CloseHandle(PRIVATE->thread);
# endif
@@ -214,6 +210,13 @@ PIThread::~PIThread() {
}
void PIThread::stop(bool wait) {
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop ..." << running_ << wait;
terminating = true;
if (wait) waitForFinish();
}
bool PIThread::start(int timer_delay) {
if (running_) return false;
//if (terminating) waitForFinish();
@@ -228,7 +231,7 @@ bool PIThread::start(int timer_delay) {
# endif
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&PRIVATE->thread, &attr, thread_function, this);
//piCout << "pthread_create" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
pthread_attr_destroy(&attr);
if (ret == 0) {
# ifdef MAC_OS
@@ -272,7 +275,7 @@ bool PIThread::startOnce() {
# endif
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&(PRIVATE->thread), &attr, thread_function_once, this);
//piCout << "pthread_create" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
pthread_attr_destroy(&attr);
if (ret == 0) {
# ifdef MAC_OS
@@ -304,17 +307,18 @@ bool PIThread::startOnce() {
void PIThread::terminate() {
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ..." << running_;
#ifdef FREERTOS
piCout << "FreeRTOS can't terminate pthreads! waiting for stop";
PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop";
stop(true);
//piCout << "stopped!";
//PICout(PICoutManipulators::DefaultControls) << "stopped!";
#else
if (PRIVATE->thread == 0) return;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
terminating = running_ = false;
tid_ = -1;
//piCout << "terminate" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
#ifndef WINDOWS
# ifdef ANDROID
pthread_kill(PRIVATE->thread, SIGTERM);
@@ -325,16 +329,13 @@ void PIThread::terminate() {
//pthread_join(PRIVATE->thread, &ret);
# endif
#else
piCout << "terminate by terminate";
while (1) {
msleep(10);
}
TerminateThread(PRIVATE->thread, 0);
CloseHandle(PRIVATE->thread);
#endif
PRIVATE->thread = 0;
end();
#endif
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
}
@@ -372,7 +373,7 @@ void PIThread::setPriority(PIThread::Priority prior) {
priority_ = prior;
#ifndef WINDOWS
if (!running_ || (PRIVATE->thread == 0)) return;
//piCout << "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));
@@ -393,6 +394,7 @@ void PIThread::setPriority(PIThread::Priority prior) {
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_)
@@ -420,7 +422,7 @@ bool PIThread::waitForStart(int timeout_msecs) {
}
void PIThread::__thread_func__(void * t) {
void PIThread::__thread_func__() {
#ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
@@ -429,61 +431,74 @@ void PIThread::__thread_func__(void * t) {
#else
//__PISetTimerResolution();
#endif
PIThread & ct = *((PIThread * )t);
#ifdef WINDOWS
ct.tid_ = GetCurrentThreadId();
tid_ = GetCurrentThreadId();
#endif
#ifdef LINUX
ct.tid_ = gettid();
tid_ = gettid();
#endif
PIINTROSPECTION_REGISTER_THREAD(ct.tid(), ct.priority(), ct.name());
REGISTER_THREAD(&ct);
ct.running_ = true;
if (ct.lockRun) ct.mutex_.lock();
ct.begin();
if (ct.lockRun) ct.mutex_.unlock();
ct.started();
while (!ct.terminating) {
ct.maybeCallQueuedEvents();
if (ct.lockRun) ct.mutex_.lock();
// piCout << "thread" << ct.name() << "..." << ct.lockRun;
ct.run();
//printf("thread %p tick\n", &ct);
if (ct.ret_func != 0) ct.ret_func(ct.data_);
if (ct.lockRun) ct.mutex_.unlock();
// piCout << "thread" << ct.name() << "done";
if (ct.delay_ > 0) {
ct.tmr_.reset();
PIINTROSPECTION_REGISTER_THREAD(tid(), priority(), name());
REGISTER_THREAD(this);
running_ = true;
if (lockRun) mutex_.lock();
begin();
if (lockRun) mutex_.unlock();
started();
while (!terminating) {
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "...";
maybeCallQueuedEvents();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "ok";
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
if (lockRun) mutex_.lock();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
run();
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) mutex_.unlock();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "...";
if (delay_ > 0) {
tmr_.reset();
double sl(0.);
while (1) {
sl = piMind(ct.delay_ - ct.tmr_.elapsed_m(), PIP_MIN_MSLEEP);
sl = piMind(delay_ - tmr_.elapsed_m(), PIP_MIN_MSLEEP);
#ifdef WINDOWS
/*if (sl <= 1. && sl >= 0.) {
piMSleep(PIP_MIN_MSLEEP);
continue;
}*/
#endif
//printf("%f %f %f\n", double(ct.delay_), ct.tmr_.elapsed_m(), sl);
if (ct.terminating) break;
//printf("%f %f %f\n", double(delay_), tmr_.elapsed_m(), sl);
if (terminating) break;
if (sl <= 0.) break;
piMSleep(sl);
}
}
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "ok";
}
ct.stopped();
if (ct.lockRun) ct.mutex_.lock();
ct.end();
if (ct.lockRun) ct.mutex_.unlock();
ct.terminating = ct.running_ = false;
ct.tid_ = -1;
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
stopped();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) mutex_.lock();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
end();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) mutex_.unlock();
terminating = running_ = false;
tid_ = -1;
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
//cout << "thread " << t << " exiting ... " << endl;
//piCout << "pthread_exit" << (ct.__privateinitializer__.p)->thread;
UNREGISTER_THREAD(&ct);
PIINTROSPECTION_UNREGISTER_THREAD(ct.tid());
piCout << "pthread_exit" << &ct;
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
#ifndef WINDOWS
pthread_detach((ct.__privateinitializer__.p)->thread);
(ct.__privateinitializer__.p)->thread = 0;
pthread_detach((__privateinitializer__.p)->thread);
(__privateinitializer__.p)->thread = 0;
#endif
#ifndef WINDOWS
pthread_exit(0);
@@ -497,7 +512,7 @@ void PIThread::__thread_func__(void * t) {
}
void PIThread::__thread_func_once__(void * t) {
void PIThread::__thread_func_once__() {
#ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
@@ -506,33 +521,32 @@ void PIThread::__thread_func_once__(void * t) {
#else
//__PISetTimerResolution();
#endif
PIThread & ct = *((PIThread * )t);
#ifdef WINDOWS
ct.tid_ = GetCurrentThreadId();
tid_ = GetCurrentThreadId();
#endif
#ifdef LINUX
ct.tid_ = gettid();
tid_ = gettid();
#endif
PIINTROSPECTION_REGISTER_THREAD(ct.tid(), ct.priority(), ct.name());
REGISTER_THREAD(&ct);
ct.running_ = true;
ct.begin();
ct.started();
if (ct.lockRun) ct.mutex_.lock();
ct.run();
if (ct.ret_func != 0) ct.ret_func(ct.data_);
if (ct.lockRun) ct.mutex_.unlock();
ct.stopped();
ct.end();
ct.terminating = ct.running_ = false;
ct.tid_ = -1;
PIINTROSPECTION_REGISTER_THREAD(tid(), priority(), name());
REGISTER_THREAD(this);
running_ = true;
begin();
started();
if (lockRun) mutex_.lock();
run();
if (ret_func != 0) ret_func(data_);
if (lockRun) mutex_.unlock();
stopped();
end();
terminating = running_ = false;
tid_ = -1;
//cout << "thread " << t << " exiting ... " << endl;
//piCout << "pthread_exit" << (ct.__privateinitializer__.p)->thread;
UNREGISTER_THREAD(&ct);
PIINTROSPECTION_UNREGISTER_THREAD(ct.tid());
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
#ifndef WINDOWS
pthread_detach((ct.__privateinitializer__.p)->thread);
(ct.__privateinitializer__.p)->thread = 0;
pthread_detach((__privateinitializer__.p)->thread);
(__privateinitializer__.p)->thread = 0;
#endif
#ifndef WINDOWS
pthread_exit(0);