version 4.6.0
PIThreadNotifier::waitFor() new method PIThread::waitForFinish() now use condvar to exit as soon as possible
This commit is contained in:
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
|||||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||||
project(PIP)
|
project(PIP)
|
||||||
set(PIP_MAJOR 4)
|
set(PIP_MAJOR 4)
|
||||||
set(PIP_MINOR 5)
|
set(PIP_MINOR 6)
|
||||||
set(PIP_REVISION 0)
|
set(PIP_REVISION 0)
|
||||||
set(PIP_SUFFIX )
|
set(PIP_SUFFIX )
|
||||||
set(PIP_COMPANY SHS)
|
set(PIP_COMPANY SHS)
|
||||||
|
|||||||
@@ -492,7 +492,8 @@ void PIString::buildData(const char * cp) const {
|
|||||||
std::string u8str = ucs2conv.to_bytes((char16_t *)d.data(), (char16_t *)d.data() + d.size());
|
std::string u8str = ucs2conv.to_bytes((char16_t *)d.data(), (char16_t *)d.data() + d.size());
|
||||||
data_ = (char *)malloc(u8str.size() + 1);
|
data_ = (char *)malloc(u8str.size() + 1);
|
||||||
strcpy(data_, u8str.c_str());
|
strcpy(data_, u8str.c_str());
|
||||||
data_size_ = u8str.size();
|
data_[u8str.size()] = '\0';
|
||||||
|
data_size_ = u8str.size();
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#include "piintrospection_threads.h"
|
#include "piintrospection_threads.h"
|
||||||
|
#include "piliterals_time.h"
|
||||||
#include "pitime.h"
|
#include "pitime.h"
|
||||||
#include "pitranslator.h"
|
#include "pitranslator.h"
|
||||||
#ifndef MICRO_PIP
|
#ifndef MICRO_PIP
|
||||||
@@ -827,26 +828,14 @@ bool PIThread::waitForFinish(PISystemTime timeout) {
|
|||||||
// timeout_msecs;
|
// timeout_msecs;
|
||||||
if (!running_) return true;
|
if (!running_) return true;
|
||||||
if (timeout.isNull()) {
|
if (timeout.isNull()) {
|
||||||
while (running_) {
|
for (;;) {
|
||||||
piMinSleep();
|
if (_waitForFinish(100_ms)) break;
|
||||||
#ifdef WINDOWS
|
|
||||||
if (!isExists(PRIVATE->thread)) {
|
|
||||||
unlock();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
tmf_.reset();
|
tmf_.reset();
|
||||||
while (running_ && tmf_.elapsed() < timeout) {
|
while (tmf_.elapsed() < timeout) {
|
||||||
piMinSleep();
|
if (_waitForFinish(100_ms)) return true;
|
||||||
#ifdef WINDOWS
|
|
||||||
if (!isExists(PRIVATE->thread)) {
|
|
||||||
unlock();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return tmf_.elapsed() < timeout;
|
return tmf_.elapsed() < timeout;
|
||||||
}
|
}
|
||||||
@@ -919,10 +908,11 @@ void PIThread::_endThread() {
|
|||||||
PIScopeExitCall ec([this] {
|
PIScopeExitCall ec([this] {
|
||||||
terminating = running_ = false;
|
terminating = running_ = false;
|
||||||
tid_ = -1;
|
tid_ = -1;
|
||||||
|
state_mutex.lock();
|
||||||
|
state_var.notifyAll();
|
||||||
|
state_mutex.unlock();
|
||||||
});
|
});
|
||||||
// while (PRIVATE->starting)
|
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
|
||||||
// piMinSleep();
|
|
||||||
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
|
|
||||||
stopped();
|
stopped();
|
||||||
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
||||||
if (lockRun) thread_mutex.lock();
|
if (lockRun) thread_mutex.lock();
|
||||||
@@ -1084,3 +1074,19 @@ void PIThread::setThreadName() {
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIThread::_waitForFinish(PISystemTime max_tm) {
|
||||||
|
if (!running_) return true;
|
||||||
|
state_mutex.lock();
|
||||||
|
state_var.waitFor(state_mutex, max_tm);
|
||||||
|
state_mutex.unlock();
|
||||||
|
if (!running_) return true;
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (!isExists(PRIVATE->thread)) {
|
||||||
|
unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#ifndef PITHREAD_H
|
#ifndef PITHREAD_H
|
||||||
#define PITHREAD_H
|
#define PITHREAD_H
|
||||||
|
|
||||||
|
#include "piconditionvar.h"
|
||||||
#include "piinit.h"
|
#include "piinit.h"
|
||||||
#include "pimutex.h"
|
#include "pimutex.h"
|
||||||
#include "piobject.h"
|
#include "piobject.h"
|
||||||
@@ -286,10 +287,11 @@ protected:
|
|||||||
PISystemTime delay_;
|
PISystemTime delay_;
|
||||||
llong tid_ = -1;
|
llong tid_ = -1;
|
||||||
void * data_ = nullptr;
|
void * data_ = nullptr;
|
||||||
mutable PIMutex thread_mutex;
|
mutable PIMutex thread_mutex, state_mutex;
|
||||||
PITimeMeasurer tmf_, tms_, tmr_;
|
PITimeMeasurer tmf_, tms_, tmr_;
|
||||||
PIThread::Priority priority_ = piNormal;
|
PIThread::Priority priority_ = piNormal;
|
||||||
ThreadFunc ret_func = nullptr;
|
ThreadFunc ret_func = nullptr;
|
||||||
|
PIConditionVariable state_var;
|
||||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -297,6 +299,7 @@ private:
|
|||||||
void _beginThread();
|
void _beginThread();
|
||||||
void _runThread();
|
void _runThread();
|
||||||
void _endThread();
|
void _endThread();
|
||||||
|
bool _waitForFinish(PISystemTime max_tm);
|
||||||
|
|
||||||
PIByteArray createThreadName(int size = 16) const;
|
PIByteArray createThreadName(int size = 16) const;
|
||||||
void setThreadName();
|
void setThreadName();
|
||||||
|
|||||||
@@ -115,6 +115,19 @@ void PIThreadNotifier::wait() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIThreadNotifier::waitFor(PISystemTime timeout) {
|
||||||
|
bool ret = false;
|
||||||
|
m.lock();
|
||||||
|
v.waitFor(m, timeout);
|
||||||
|
if (cnt > 0) {
|
||||||
|
cnt--;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
m.unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \~\details
|
//! \~\details
|
||||||
//! \~english
|
//! \~english
|
||||||
//! If many threads waiting, then notify randomly one.\n
|
//! If many threads waiting, then notify randomly one.\n
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ public:
|
|||||||
//! \~russian Начать ожидание, продолжает когда другой поток вызовет \a notify()
|
//! \~russian Начать ожидание, продолжает когда другой поток вызовет \a notify()
|
||||||
void wait();
|
void wait();
|
||||||
|
|
||||||
|
//! \~english Start waiting no longer than "timeout", return \b true if other thread call \a notify(), \b false if timeout expired
|
||||||
|
//! \~russian Начать ожидание не дольше чем "timeout", возвращает \b true когда другой поток вызовал \a notify(), \b false если таймаут
|
||||||
|
//! истек
|
||||||
|
bool waitFor(PISystemTime timeout);
|
||||||
|
|
||||||
//! \~english Notify one waiting thread, which waiting on \a wait() function
|
//! \~english Notify one waiting thread, which waiting on \a wait() function
|
||||||
//! \~russian Уведомить один из ожидающих потоков, которые висят на методе \a wait()
|
//! \~russian Уведомить один из ожидающих потоков, которые висят на методе \a wait()
|
||||||
void notify();
|
void notify();
|
||||||
|
|||||||
Reference in New Issue
Block a user