version 4.6.0

PIThreadNotifier::waitFor() new method
PIThread::waitForFinish() now use condvar to exit as soon as possible
This commit is contained in:
2025-01-15 17:57:16 +03:00
parent 60d2a83df5
commit 0dd47f50a0
6 changed files with 50 additions and 22 deletions

View File

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(PIP)
set(PIP_MAJOR 4)
set(PIP_MINOR 5)
set(PIP_MINOR 6)
set(PIP_REVISION 0)
set(PIP_SUFFIX )
set(PIP_COMPANY SHS)

View File

@@ -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());
data_ = (char *)malloc(u8str.size() + 1);
strcpy(data_, u8str.c_str());
data_size_ = u8str.size();
data_[u8str.size()] = '\0';
data_size_ = u8str.size();
# endif
#endif
}

View File

@@ -21,6 +21,7 @@
#include "piincludes_p.h"
#include "piintrospection_threads.h"
#include "piliterals_time.h"
#include "pitime.h"
#include "pitranslator.h"
#ifndef MICRO_PIP
@@ -827,26 +828,14 @@ bool PIThread::waitForFinish(PISystemTime timeout) {
// timeout_msecs;
if (!running_) return true;
if (timeout.isNull()) {
while (running_) {
piMinSleep();
#ifdef WINDOWS
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
#endif
for (;;) {
if (_waitForFinish(100_ms)) break;
}
return true;
}
tmf_.reset();
while (running_ && tmf_.elapsed() < timeout) {
piMinSleep();
#ifdef WINDOWS
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
#endif
while (tmf_.elapsed() < timeout) {
if (_waitForFinish(100_ms)) return true;
}
return tmf_.elapsed() < timeout;
}
@@ -919,10 +908,11 @@ void PIThread::_endThread() {
PIScopeExitCall ec([this] {
terminating = running_ = false;
tid_ = -1;
state_mutex.lock();
state_var.notifyAll();
state_mutex.unlock();
});
// while (PRIVATE->starting)
// piMinSleep();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
stopped();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) thread_mutex.lock();
@@ -1084,3 +1074,19 @@ void PIThread::setThreadName() {
# 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;
}

View File

@@ -26,6 +26,7 @@
#ifndef PITHREAD_H
#define PITHREAD_H
#include "piconditionvar.h"
#include "piinit.h"
#include "pimutex.h"
#include "piobject.h"
@@ -286,10 +287,11 @@ protected:
PISystemTime delay_;
llong tid_ = -1;
void * data_ = nullptr;
mutable PIMutex thread_mutex;
mutable PIMutex thread_mutex, state_mutex;
PITimeMeasurer tmf_, tms_, tmr_;
PIThread::Priority priority_ = piNormal;
ThreadFunc ret_func = nullptr;
PIConditionVariable state_var;
PRIVATE_DECLARATION(PIP_EXPORT)
private:
@@ -297,6 +299,7 @@ private:
void _beginThread();
void _runThread();
void _endThread();
bool _waitForFinish(PISystemTime max_tm);
PIByteArray createThreadName(int size = 16) const;
void setThreadName();

View File

@@ -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
//! \~english
//! If many threads waiting, then notify randomly one.\n

View File

@@ -37,6 +37,11 @@ public:
//! \~russian Начать ожидание, продолжает когда другой поток вызовет \a notify()
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
//! \~russian Уведомить один из ожидающих потоков, которые висят на методе \a wait()
void notify();