remove msleep, clean PIConditionVariable, rewrite pipipelinethread, etc...
This commit is contained in:
@@ -36,7 +36,6 @@ PRIVATE_DEFINITION_START(PIConditionVariable)
|
||||
#else
|
||||
pthread_cond_t nativeHandle;
|
||||
#endif
|
||||
bool isDestroying;
|
||||
PRIVATE_DEFINITION_END(PIConditionVariable)
|
||||
|
||||
|
||||
@@ -44,7 +43,6 @@ PIConditionVariable::PIConditionVariable() {
|
||||
#ifdef WINDOWS
|
||||
InitializeConditionVariable(&PRIVATE->nativeHandle);
|
||||
#else
|
||||
PRIVATE->isDestroying = false;
|
||||
|
||||
pthread_condattr_t condattr;
|
||||
pthread_condattr_init(&condattr);
|
||||
@@ -84,7 +82,6 @@ void PIConditionVariable::wait(PIMutex& lk, const std::function<bool()>& conditi
|
||||
#else
|
||||
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
|
||||
#endif
|
||||
if (PRIVATE->isDestroying) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +97,6 @@ bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) {
|
||||
st.toTimespec(&expire_ts);
|
||||
isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) == 0;
|
||||
#endif
|
||||
if (PRIVATE->isDestroying) return false;
|
||||
return isNotTimeout;
|
||||
}
|
||||
|
||||
@@ -127,7 +123,6 @@ bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::functio
|
||||
bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) != 0;
|
||||
#endif
|
||||
if (isTimeout) return false;
|
||||
if (PRIVATE->isDestroying) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "pithread.h"
|
||||
#include "piqueue.h"
|
||||
#include "piconditionvar.h"
|
||||
|
||||
|
||||
template <typename Tin, typename Tout>
|
||||
class PIPipelineThread : public PIThread
|
||||
@@ -35,10 +37,10 @@ public:
|
||||
cnt = 0;
|
||||
max_size = 0;
|
||||
wait_next_pipe = false;
|
||||
next_overload = false;
|
||||
}
|
||||
~PIPipelineThread() {
|
||||
stop();
|
||||
cv.notifyAll();
|
||||
if (!waitForFinish(1000)) {
|
||||
piCoutObj << "terminating self thread";
|
||||
terminate();
|
||||
@@ -46,21 +48,27 @@ public:
|
||||
}
|
||||
template <typename T>
|
||||
void connectTo(PIPipelineThread<Tout, T> * next) {
|
||||
CONNECT2(void, Tout, bool *, this, calculated, next, enqueue)
|
||||
CONNECT3(void, Tout, bool, bool *, this, calculated, next, enqueue)
|
||||
}
|
||||
EVENT2(calculated, const Tout &, v, bool *, overload)
|
||||
void enqueue(const Tin &v) {enqueue(v, 0);}
|
||||
EVENT_HANDLER2(void, enqueue, const Tin &, v, bool *, overload) {
|
||||
EVENT3(calculated, const Tout &, v, bool, wait, bool *, overload)
|
||||
EVENT_HANDLER3(void, enqueue, const Tin &, v, bool, wait, bool *, overload) {
|
||||
mutex.lock();
|
||||
//piCoutObj << "enque" << overload;
|
||||
if (wait && max_size != 0) {
|
||||
mutex_wait.lock();
|
||||
while (in.size() >= max_size) cv_wait.wait(mutex_wait);
|
||||
mutex_wait.unlock();
|
||||
}
|
||||
if (max_size == 0 || in.size() < max_size) {
|
||||
in.enqueue(v);
|
||||
cv.notifyAll();
|
||||
if (overload) *overload = false;
|
||||
} else {
|
||||
if (overload) *overload = true;
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
void enqueue(const Tin &v, bool wait = false) {enqueue(v, wait, nullptr);}
|
||||
const ullong * counterPtr() const {return &cnt;}
|
||||
ullong counter() const {return cnt;}
|
||||
bool isEmpty() {
|
||||
@@ -79,15 +87,18 @@ public:
|
||||
}
|
||||
void clear() {
|
||||
mutex.lock();
|
||||
mutex_wait.lock();
|
||||
in.clear();
|
||||
next_overload = false;
|
||||
cv_wait.notifyAll();
|
||||
mutex_wait.unlock();
|
||||
mutex.unlock();
|
||||
}
|
||||
void stopCalc(int wait_delay = 100) {
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
cv.notifyAll();
|
||||
if (!waitForFinish(wait_delay)) {
|
||||
mutex_l.unlock();
|
||||
mutex_last.unlock();
|
||||
mutex.unlock();
|
||||
terminate();
|
||||
}
|
||||
@@ -95,18 +106,14 @@ public:
|
||||
}
|
||||
Tout getLast() {
|
||||
Tout ret;
|
||||
mutex_l.lock();
|
||||
mutex_last.lock();
|
||||
ret = last;
|
||||
mutex_l.unlock();
|
||||
mutex_last.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint maxQueSize() {
|
||||
uint ret;
|
||||
mutex.lock();
|
||||
ret = max_size;
|
||||
mutex.unlock();
|
||||
return ret;
|
||||
return max_size;
|
||||
}
|
||||
|
||||
void setMaxQueSize(uint count) {
|
||||
@@ -127,39 +134,35 @@ protected:
|
||||
private:
|
||||
void begin() {cnt = 0;}
|
||||
void run() {
|
||||
//piCoutObj << "run ...";
|
||||
mutex.lock();
|
||||
if (in.isEmpty()) {
|
||||
mutex.unlock();
|
||||
piMSleep(10);
|
||||
//piCoutObj << "run in empty";
|
||||
return;
|
||||
}
|
||||
if (next_overload && wait_next_pipe) {
|
||||
mutex.unlock();
|
||||
//piCoutObj << "wait" << &next_overload;
|
||||
calculated(last, &next_overload);
|
||||
piMSleep(10);
|
||||
} else {
|
||||
Tin t = in.dequeue();
|
||||
mutex.unlock();
|
||||
bool ok = true;
|
||||
Tout r = calc(t, ok);
|
||||
if (ok) {
|
||||
mutex_l.lock();
|
||||
last = r;
|
||||
mutex_l.unlock();
|
||||
cnt++;
|
||||
//piCoutObj << "calc ok" << &next_overload;
|
||||
calculated(r, &next_overload);
|
||||
while (in.isEmpty()) {
|
||||
cv.wait(mutex);
|
||||
if (terminating) {
|
||||
mutex.unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
mutex_wait.lock();
|
||||
Tin t = in.dequeue();
|
||||
mutex.unlock();
|
||||
cv_wait.notifyAll();
|
||||
mutex_wait.unlock();
|
||||
bool ok = true;
|
||||
Tout r = calc(t, ok);
|
||||
if (ok) {
|
||||
mutex_last.lock();
|
||||
last = r;
|
||||
mutex_last.unlock();
|
||||
cnt++;
|
||||
//piCoutObj << "calc ok";
|
||||
calculated(r, wait_next_pipe);
|
||||
}
|
||||
//piCoutObj << "run ok";
|
||||
}
|
||||
PIMutex mutex;
|
||||
PIMutex mutex_l;
|
||||
PIMutex mutex, mutex_wait;
|
||||
PIConditionVariable cv, cv_wait;
|
||||
PIMutex mutex_last;
|
||||
bool wait_next_pipe;
|
||||
bool next_overload;
|
||||
ullong cnt;
|
||||
PIQueue<Tin> in;
|
||||
Tout last;
|
||||
|
||||
@@ -63,7 +63,7 @@ event started();
|
||||
while (isRunning()) {
|
||||
run();
|
||||
ThreadFunc();
|
||||
msleep(timer_delay);
|
||||
piMSleep(timer_delay);
|
||||
}
|
||||
event stopped();
|
||||
end();
|
||||
@@ -402,7 +402,7 @@ bool PIThread::waitForFinish(int timeout_msecs) {
|
||||
if (!running_) return true;
|
||||
if (timeout_msecs < 0) {
|
||||
while (running_) {
|
||||
msleep(PIP_MIN_MSLEEP);
|
||||
piMSleep(PIP_MIN_MSLEEP);
|
||||
#ifdef WINDOWS
|
||||
if (!isExists(PRIVATE->thread)) {
|
||||
unlock();
|
||||
@@ -414,7 +414,7 @@ bool PIThread::waitForFinish(int timeout_msecs) {
|
||||
}
|
||||
tmf_.reset();
|
||||
while (running_ && tmf_.elapsed_m() < timeout_msecs) {
|
||||
msleep(PIP_MIN_MSLEEP);
|
||||
piMSleep(PIP_MIN_MSLEEP);
|
||||
#ifdef WINDOWS
|
||||
if (!isExists(PRIVATE->thread)) {
|
||||
unlock();
|
||||
@@ -430,12 +430,12 @@ bool PIThread::waitForStart(int timeout_msecs) {
|
||||
if (running_) return true;
|
||||
if (timeout_msecs < 0) {
|
||||
while (!running_)
|
||||
msleep(PIP_MIN_MSLEEP);
|
||||
piMSleep(PIP_MIN_MSLEEP);
|
||||
return true;
|
||||
}
|
||||
tms_.reset();
|
||||
while (!running_ && tms_.elapsed_m() < timeout_msecs)
|
||||
msleep(PIP_MIN_MSLEEP);
|
||||
piMSleep(PIP_MIN_MSLEEP);
|
||||
return tms_.elapsed_m() < timeout_msecs;
|
||||
}
|
||||
|
||||
@@ -456,9 +456,9 @@ void PIThread::_beginThread() {
|
||||
PIINTROSPECTION_THREAD_START(this);
|
||||
REGISTER_THREAD(this);
|
||||
running_ = true;
|
||||
if (lockRun) mutex_.lock();
|
||||
if (lockRun) thread_mutex.lock();
|
||||
begin();
|
||||
if (lockRun) mutex_.unlock();
|
||||
if (lockRun) thread_mutex.unlock();
|
||||
started();
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ void PIThread::_beginThread() {
|
||||
void PIThread::_runThread() {
|
||||
PIINTROSPECTION_THREAD_RUN(this);
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
|
||||
if (lockRun) mutex_.lock();
|
||||
if (lockRun) thread_mutex.lock();
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
|
||||
#ifdef PIP_INTROSPECTION
|
||||
@@ -482,7 +482,7 @@ void PIThread::_runThread() {
|
||||
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();
|
||||
if (lockRun) thread_mutex.unlock();
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
|
||||
}
|
||||
|
||||
@@ -491,11 +491,11 @@ void PIThread::_endThread() {
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
|
||||
stopped();
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
||||
if (lockRun) mutex_.lock();
|
||||
if (lockRun) thread_mutex.lock();
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
|
||||
end();
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
||||
if (lockRun) mutex_.unlock();
|
||||
if (lockRun) thread_mutex.unlock();
|
||||
terminating = running_ = false;
|
||||
tid_ = -1;
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
|
||||
|
||||
@@ -131,11 +131,15 @@ public:
|
||||
|
||||
//! @brief Set necessity of lock every \a run with internal mutex
|
||||
void needLockRun(bool need) {lockRun = need;}
|
||||
EVENT_HANDLER0(void, lock) {mutex_.lock();}
|
||||
EVENT_HANDLER0(void, unlock) {mutex_.unlock();}
|
||||
|
||||
//! @brief Lock internal mutex
|
||||
EVENT_HANDLER0(void, lock) const {thread_mutex.lock();}
|
||||
|
||||
//! @brief Unlock internal mutex
|
||||
EVENT_HANDLER0(void, unlock) const {thread_mutex.unlock();}
|
||||
|
||||
//! @brief Returns internal mutex
|
||||
PIMutex & mutex() {return mutex_;}
|
||||
PIMutex & mutex() const {return thread_mutex;}
|
||||
|
||||
//! @brief Returns thread ID
|
||||
llong tid() const {return tid_;}
|
||||
@@ -239,7 +243,7 @@ protected:
|
||||
int delay_, policy_;
|
||||
llong tid_;
|
||||
void * data_;
|
||||
mutable PIMutex mutex_;
|
||||
mutable PIMutex thread_mutex;
|
||||
PITimeMeasurer tmf_, tms_, tmr_;
|
||||
PIThread::Priority priority_;
|
||||
ThreadFunc ret_func;
|
||||
|
||||
@@ -648,11 +648,11 @@ bool PITimer::stop(bool wait) {
|
||||
bool PITimer::waitForFinish(int timeout_msecs) {
|
||||
if (timeout_msecs < 0) {
|
||||
while (isRunning())
|
||||
msleep(PIP_MIN_MSLEEP);
|
||||
piMSleep(PIP_MIN_MSLEEP);
|
||||
return true;
|
||||
}
|
||||
PITimeMeasurer tm;
|
||||
while (isRunning() && tm.elapsed_m() < timeout_msecs)
|
||||
msleep(PIP_MIN_MSLEEP);
|
||||
piMSleep(PIP_MIN_MSLEEP);
|
||||
return tm.elapsed_m() < timeout_msecs;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user