git-svn-id: svn://db.shs.com.ru/pip@802 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
#include "piincludes_p.h"
|
||||
#include "pithread.h"
|
||||
#include "pisystemtests.h"
|
||||
#include "piintrospection_proxy.h"
|
||||
#include "piintrospection_threads.h"
|
||||
#include <signal.h>
|
||||
#ifdef WINDOWS
|
||||
# define __THREAD_FUNC_RET__ uint __stdcall
|
||||
@@ -160,6 +160,7 @@ PRIVATE_DEFINITION_END(PIThread)
|
||||
|
||||
|
||||
PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() {
|
||||
PIINTROSPECTION_THREAD_NEW(this);
|
||||
piMonitor.threads++;
|
||||
tid_ = -1;
|
||||
PRIVATE->thread = 0;
|
||||
@@ -173,6 +174,7 @@ PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay)
|
||||
|
||||
|
||||
PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
|
||||
PIINTROSPECTION_THREAD_NEW(this);
|
||||
piMonitor.threads++;
|
||||
tid_ = -1;
|
||||
PRIVATE->thread = 0;
|
||||
@@ -185,6 +187,7 @@ PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
|
||||
|
||||
|
||||
PIThread::~PIThread() {
|
||||
PIINTROSPECTION_THREAD_DELETE(this);
|
||||
piMonitor.threads--;
|
||||
if (!running_ || PRIVATE->thread == 0) return;
|
||||
#ifdef FREERTOS
|
||||
@@ -220,91 +223,15 @@ void PIThread::stop(bool wait) {
|
||||
bool PIThread::start(int timer_delay) {
|
||||
if (running_) return false;
|
||||
//if (terminating) waitForFinish();
|
||||
terminating = false;
|
||||
running_ = true;
|
||||
delay_ = timer_delay;
|
||||
#ifndef WINDOWS
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
# ifndef ANDROID
|
||||
//pthread_attr_setschedparam(&attr, &(PRIVATE->sparam));
|
||||
# endif
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
int ret = pthread_create(&PRIVATE->thread, &attr, thread_function, this);
|
||||
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
|
||||
pthread_attr_destroy(&attr);
|
||||
if (ret == 0) {
|
||||
pthread_setname_np(PRIVATE->thread, ((PIString&)name().resize(15, '\0')).dataAscii());
|
||||
# ifdef MAC_OS
|
||||
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
|
||||
# else
|
||||
# ifdef FREERTOS
|
||||
tid_ = PRIVATE->thread;
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
if (PRIVATE->thread != 0) CloseHandle(PRIVATE->thread);
|
||||
# ifdef CC_GCC
|
||||
PRIVATE->thread = (void *)_beginthreadex(0, 0, thread_function, this, 0, 0);
|
||||
# else
|
||||
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, this, 0, 0);
|
||||
# endif
|
||||
if (PRIVATE->thread != 0) {
|
||||
#endif
|
||||
setPriority(priority_);
|
||||
return true;
|
||||
} else {
|
||||
running_ = false;
|
||||
PRIVATE->thread = 0;
|
||||
piCoutObj << "Error: Can`t start new thread:" << errorString();
|
||||
}
|
||||
running_ = false;
|
||||
return false;
|
||||
return _startThread((void*)thread_function);
|
||||
}
|
||||
|
||||
|
||||
bool PIThread::startOnce() {
|
||||
if (terminating) waitForFinish();
|
||||
if (running_) return false;
|
||||
terminating = false;
|
||||
running_ = true;
|
||||
#ifndef WINDOWS
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
# ifndef ANDROID
|
||||
//pthread_attr_setschedparam(&attr, &(PRIVATE->sparam));
|
||||
# endif
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
int ret = pthread_create(&(PRIVATE->thread), &attr, thread_function_once, this);
|
||||
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
|
||||
pthread_attr_destroy(&attr);
|
||||
if (ret == 0) {
|
||||
pthread_setname_np(PRIVATE->thread, ((PIString&)name().resize(15, '\0')).dataAscii());
|
||||
# ifdef MAC_OS
|
||||
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
|
||||
# else
|
||||
# ifdef FREERTOS
|
||||
tid_ = PRIVATE->thread;
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
if (PRIVATE->thread != 0) CloseHandle(PRIVATE->thread);
|
||||
# ifdef CC_GCC
|
||||
PRIVATE->thread = (void *)_beginthreadex(0, 0, thread_function_once, this, 0, 0);
|
||||
# else
|
||||
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function_once, this, 0, 0);
|
||||
# endif
|
||||
if (PRIVATE->thread != 0) {
|
||||
#endif
|
||||
setPriority(priority_);
|
||||
return true;
|
||||
} else {
|
||||
running_ = false;
|
||||
PRIVATE->thread = 0;
|
||||
piCoutObj << "Error: Can`t start new thread:" << errorString();
|
||||
}
|
||||
running_ = false;
|
||||
return false;
|
||||
return _startThread((void*)thread_function_once);
|
||||
}
|
||||
|
||||
|
||||
@@ -317,7 +244,6 @@ void PIThread::terminate() {
|
||||
#else
|
||||
if (PRIVATE->thread == 0) return;
|
||||
UNREGISTER_THREAD(this);
|
||||
PIINTROSPECTION_UNREGISTER_THREAD(tid());
|
||||
terminating = running_ = false;
|
||||
tid_ = -1;
|
||||
//PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
|
||||
@@ -337,6 +263,7 @@ void PIThread::terminate() {
|
||||
PRIVATE->thread = 0;
|
||||
end();
|
||||
#endif
|
||||
PIINTROSPECTION_THREAD_STOP(this);
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
|
||||
}
|
||||
|
||||
@@ -370,6 +297,50 @@ int PIThread::priority2System(PIThread::Priority p) {
|
||||
}
|
||||
|
||||
|
||||
bool PIThread::_startThread(void * func) {
|
||||
//if (terminating) waitForFinish();
|
||||
terminating = false;
|
||||
running_ = true;
|
||||
#ifndef WINDOWS
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
# ifndef ANDROID
|
||||
//pthread_attr_setschedparam(&attr, &(PRIVATE->sparam));
|
||||
# endif
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
int ret = pthread_create(&PRIVATE->thread, &attr, (void*(*)(void*))func, this);
|
||||
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
|
||||
pthread_attr_destroy(&attr);
|
||||
if (ret == 0) {
|
||||
pthread_setname_np(PRIVATE->thread, ((PIString&)name().resize(15, '\0')).dataAscii());
|
||||
# ifdef MAC_OS
|
||||
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
|
||||
# else
|
||||
# ifdef FREERTOS
|
||||
tid_ = PRIVATE->thread;
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
|
||||
# ifdef CC_GCC
|
||||
PRIVATE->thread = (void *)_beginthreadex(0, 0, (unsigned(__stdcall*)(void*))func, this, 0, 0);
|
||||
# else
|
||||
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
|
||||
# endif
|
||||
if (PRIVATE->thread != 0) {
|
||||
#endif
|
||||
setPriority(priority_);
|
||||
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) {
|
||||
#ifndef FREERTOS // FreeRTOS can't change priority runtime
|
||||
priority_ = prior;
|
||||
@@ -451,7 +422,7 @@ bool PIThread::waitForStart(int timeout_msecs) {
|
||||
}
|
||||
|
||||
|
||||
void PIThread::__thread_func__() {
|
||||
void PIThread::_beginThread() {
|
||||
#ifndef WINDOWS
|
||||
# if !defined(ANDROID) && !defined(FREERTOS)
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
|
||||
@@ -466,50 +437,35 @@ void PIThread::__thread_func__() {
|
||||
#ifdef LINUX
|
||||
tid_ = gettid();
|
||||
#endif
|
||||
PIINTROSPECTION_REGISTER_THREAD(tid(), priority(), name());
|
||||
PIINTROSPECTION_THREAD_START(this);
|
||||
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(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(delay_), tmr_.elapsed_m(), sl);
|
||||
if (terminating) break;
|
||||
if (sl <= 0.) break;
|
||||
piMSleep(sl);
|
||||
}
|
||||
}
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "ok";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIThread::_runThread() {
|
||||
PIINTROSPECTION_THREAD_RUN(this);
|
||||
//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";
|
||||
}
|
||||
|
||||
|
||||
void PIThread::_endThread() {
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
|
||||
stopped();
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
||||
@@ -524,10 +480,10 @@ void PIThread::__thread_func__() {
|
||||
//cout << "thread " << t << " exiting ... " << endl;
|
||||
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
|
||||
UNREGISTER_THREAD(this);
|
||||
PIINTROSPECTION_UNREGISTER_THREAD(tid());
|
||||
PIINTROSPECTION_THREAD_STOP(this);
|
||||
#ifndef WINDOWS
|
||||
pthread_detach((__privateinitializer__.p)->thread);
|
||||
(__privateinitializer__.p)->thread = 0;
|
||||
pthread_detach(PRIVATE->thread);
|
||||
PRIVATE->thread = 0;
|
||||
#endif
|
||||
#ifndef WINDOWS
|
||||
pthread_exit(0);
|
||||
@@ -541,50 +497,34 @@ void PIThread::__thread_func__() {
|
||||
}
|
||||
|
||||
|
||||
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__() {
|
||||
#ifndef WINDOWS
|
||||
# if !defined(ANDROID) && !defined(FREERTOS)
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
# endif
|
||||
#else
|
||||
//__PISetTimerResolution();
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
tid_ = GetCurrentThreadId();
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
tid_ = gettid();
|
||||
#endif
|
||||
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(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
|
||||
UNREGISTER_THREAD(this);
|
||||
PIINTROSPECTION_UNREGISTER_THREAD(tid());
|
||||
#ifndef WINDOWS
|
||||
pthread_detach((__privateinitializer__.p)->thread);
|
||||
(__privateinitializer__.p)->thread = 0;
|
||||
#endif
|
||||
#ifndef WINDOWS
|
||||
pthread_exit(0);
|
||||
#else
|
||||
# ifdef CC_GCC
|
||||
_endthreadex(0);
|
||||
# else
|
||||
ExitThread(0);
|
||||
# endif
|
||||
#endif
|
||||
_beginThread();
|
||||
_runThread();
|
||||
_endThread();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user