Merge branch 'thread' of https://git.shs.tools/SHS/pip into thread
This commit is contained in:
@@ -839,7 +839,7 @@ PIObject::Deleter::Deleter() {
|
|||||||
PRIVATE->thread.setSlot([this](){
|
PRIVATE->thread.setSlot([this](){
|
||||||
PIVector<PIObject*> oq;
|
PIVector<PIObject*> oq;
|
||||||
PRIVATE->thread.lock();
|
PRIVATE->thread.lock();
|
||||||
while(PRIVATE->obj_queue.isEmpty()) PRIVATE->cond_var.wait(PRIVATE->thread.mutex());
|
PRIVATE->cond_var.wait(PRIVATE->thread.mutex());
|
||||||
oq.swap(PRIVATE->obj_queue);
|
oq.swap(PRIVATE->obj_queue);
|
||||||
PRIVATE->thread.unlock();
|
PRIVATE->thread.unlock();
|
||||||
for (PIObject * o : oq) deleteObject(o);
|
for (PIObject * o : oq) deleteObject(o);
|
||||||
@@ -851,7 +851,9 @@ PIObject::Deleter::Deleter() {
|
|||||||
PIObject::Deleter::~Deleter() {
|
PIObject::Deleter::~Deleter() {
|
||||||
//piCout << "~Deleter ...";
|
//piCout << "~Deleter ...";
|
||||||
PRIVATE->thread.stop();
|
PRIVATE->thread.stop();
|
||||||
|
PRIVATE->thread.mutex().lock();
|
||||||
PRIVATE->cond_var.notifyAll();
|
PRIVATE->cond_var.notifyAll();
|
||||||
|
PRIVATE->thread.mutex().unlock();
|
||||||
PRIVATE->thread.waitForFinish();
|
PRIVATE->thread.waitForFinish();
|
||||||
for (PIObject * o : PRIVATE->obj_queue) deleteObject(o);
|
for (PIObject * o : PRIVATE->obj_queue) deleteObject(o);
|
||||||
//piCout << "~Deleter ok";
|
//piCout << "~Deleter ok";
|
||||||
|
|||||||
@@ -95,6 +95,27 @@ bool PIWaitEvent::wait(int fd, CheckRole role) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIWaitEvent::sleep(int us) {
|
||||||
|
if (!isCreate()) return false;
|
||||||
|
#ifdef WINDOWS
|
||||||
|
DWORD ret = WaitForSingleObjectEx(event, us / 1000, TRUE);
|
||||||
|
ResetEvent(event);
|
||||||
|
return ret == WAIT_TIMEOUT;
|
||||||
|
#else
|
||||||
|
int nfds = pipe_fd[ReadEnd] + 1;
|
||||||
|
FD_ZERO(&(fds[CheckRead]));
|
||||||
|
FD_SET(pipe_fd[ReadEnd], &(fds[CheckRead]));
|
||||||
|
timeval timeout;
|
||||||
|
timeout.tv_sec = us / 1000000;
|
||||||
|
timeout.tv_usec = us % 1000000;
|
||||||
|
int ret = ::select(nfds, &(fds[CheckRead]), nullptr, nullptr, &timeout);
|
||||||
|
int buf = 0;
|
||||||
|
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0);
|
||||||
|
return ret == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIWaitEvent::interrupt() {
|
void PIWaitEvent::interrupt() {
|
||||||
if (!isCreate()) return;
|
if (!isCreate()) return;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class PIWaitEvent {
|
class PIP_EXPORT PIWaitEvent {
|
||||||
public:
|
public:
|
||||||
~PIWaitEvent();
|
~PIWaitEvent();
|
||||||
|
|
||||||
@@ -44,6 +44,7 @@ public:
|
|||||||
void create();
|
void create();
|
||||||
void destroy();
|
void destroy();
|
||||||
bool wait(int fd = -1, CheckRole role = CheckRead);
|
bool wait(int fd = -1, CheckRole role = CheckRead);
|
||||||
|
bool sleep(int us); // return if sleep done
|
||||||
void interrupt();
|
void interrupt();
|
||||||
bool isCreate() const;
|
bool isCreate() const;
|
||||||
void * getEvent() const; // WINDOWS only
|
void * getEvent() const; // WINDOWS only
|
||||||
|
|||||||
@@ -485,7 +485,7 @@ void __PIThreadCollection::stoppedAuto() {
|
|||||||
auto_mutex.lock();
|
auto_mutex.lock();
|
||||||
auto_threads_.removeAll(t);
|
auto_threads_.removeAll(t);
|
||||||
auto_mutex.unlock();
|
auto_mutex.unlock();
|
||||||
delete t;
|
t->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
|
#include "piconditionvar.h"
|
||||||
#ifdef PIP_TIMER_RT
|
#ifdef PIP_TIMER_RT
|
||||||
# include <csignal>
|
# include <csignal>
|
||||||
#endif
|
#endif
|
||||||
@@ -187,9 +188,11 @@ private:
|
|||||||
virtual bool stopTimer(bool wait);
|
virtual bool stopTimer(bool wait);
|
||||||
static void threadFuncS(void * d) {((_PITimerImp_Thread*)d)->threadFunc();}
|
static void threadFuncS(void * d) {((_PITimerImp_Thread*)d)->threadFunc();}
|
||||||
void adjustTimes();
|
void adjustTimes();
|
||||||
|
bool smallWait(int ms);
|
||||||
|
|
||||||
PIThread thread_;
|
PIThread thread_;
|
||||||
PISystemTime st_time, st_inc, st_wait, st_odt;
|
PISystemTime st_time, st_inc, st_wait, st_odt;
|
||||||
|
PIConditionVariable event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -235,9 +238,9 @@ private:
|
|||||||
|
|
||||||
_PITimerImp_Thread::_PITimerImp_Thread() {
|
_PITimerImp_Thread::_PITimerImp_Thread() {
|
||||||
thread_.setName("__S__PITimerImp_Thread::thread");
|
thread_.setName("__S__PITimerImp_Thread::thread");
|
||||||
wait_dt = 100;
|
wait_dt = 1000;
|
||||||
wait_dd = 200;
|
wait_dd = 2000;
|
||||||
wait_tick = 10;
|
wait_tick = 1000;
|
||||||
//piCout << "_PITimerImp_Thread" << this << ", thread& =" << &thread_;
|
//piCout << "_PITimerImp_Thread" << this << ", thread& =" << &thread_;
|
||||||
//piCout << "new _PITimerImp_Thread";
|
//piCout << "new _PITimerImp_Thread";
|
||||||
}
|
}
|
||||||
@@ -275,6 +278,9 @@ bool _PITimerImp_Thread::startTimer(double interval_ms) {
|
|||||||
|
|
||||||
bool _PITimerImp_Thread::stopTimer(bool wait) {
|
bool _PITimerImp_Thread::stopTimer(bool wait) {
|
||||||
thread_.stop();
|
thread_.stop();
|
||||||
|
thread_.mutex().lock();
|
||||||
|
event.notifyAll();
|
||||||
|
thread_.mutex().unlock();
|
||||||
if (wait) return thread_.waitForFinish();
|
if (wait) return thread_.waitForFinish();
|
||||||
// if (wait)
|
// if (wait)
|
||||||
// if (!thread_.waitForFinish(10))
|
// if (!thread_.waitForFinish(10))
|
||||||
@@ -296,10 +302,10 @@ bool _PITimerImp_Thread::threadFunc() {
|
|||||||
dwt = st_time - PISystemTime::current(true);
|
dwt = st_time - PISystemTime::current(true);
|
||||||
if (wth > 0) {
|
if (wth > 0) {
|
||||||
if (dwt.toMilliseconds() > wth + 1.) {
|
if (dwt.toMilliseconds() > wth + 1.) {
|
||||||
piMSleep(wth);
|
smallWait(wth);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
dwt.sleep();
|
if (!smallWait(dwt.toMilliseconds())) return false;
|
||||||
deferred_ = false;
|
deferred_ = false;
|
||||||
st_time = PISystemTime::current(true);
|
st_time = PISystemTime::current(true);
|
||||||
}
|
}
|
||||||
@@ -318,11 +324,11 @@ bool _PITimerImp_Thread::threadFunc() {
|
|||||||
}
|
}
|
||||||
if (wait_tick > 0) {
|
if (wait_tick > 0) {
|
||||||
if (st_wait.toMilliseconds() > wait_tick + 1.) {
|
if (st_wait.toMilliseconds() > wait_tick + 1.) {
|
||||||
piMSleep(wait_tick);
|
smallWait(wait_tick);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
//piCout << &thread_ << "sleep for" << st_wait;
|
//piCout << &thread_ << "sleep for" << st_wait;
|
||||||
st_wait.sleep();
|
if (!smallWait(st_wait.toMilliseconds())) return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (st_wait.toMilliseconds() > 0.1)
|
if (st_wait.toMilliseconds() > 0.1)
|
||||||
@@ -363,6 +369,14 @@ void _PITimerImp_Thread::adjustTimes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool _PITimerImp_Thread::smallWait(int ms) {
|
||||||
|
thread_.mutex().lock();
|
||||||
|
event.waitFor(thread_.mutex(), ms);
|
||||||
|
thread_.mutex().unlock();
|
||||||
|
return !thread_.isStopping();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PIP_TIMER_RT
|
#ifdef PIP_TIMER_RT
|
||||||
|
|||||||
16
main.cpp
16
main.cpp
@@ -3,6 +3,7 @@
|
|||||||
#include "pibytearray.h"
|
#include "pibytearray.h"
|
||||||
#include "pimathbase.h"
|
#include "pimathbase.h"
|
||||||
#include "pijson.h"
|
#include "pijson.h"
|
||||||
|
#include "piwaitevent_p.h"
|
||||||
|
|
||||||
using namespace PICoutManipulators;
|
using namespace PICoutManipulators;
|
||||||
|
|
||||||
@@ -88,6 +89,21 @@ void phase(const char * msg) {
|
|||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
piCout << "main";
|
piCout << "main";
|
||||||
|
|
||||||
|
PITimer timer;
|
||||||
|
timer.setSlot([](){
|
||||||
|
static int cnt = 0;
|
||||||
|
piCout << "tick" << ++cnt;
|
||||||
|
});
|
||||||
|
timer.start(500);
|
||||||
|
|
||||||
|
piSleep(1.12);
|
||||||
|
piCout << "end";
|
||||||
|
PITimeMeasurer tm;
|
||||||
|
timer.stop();
|
||||||
|
double tm_ms = tm.elapsed_m();
|
||||||
|
piCout << "stop took" << tm_ms;
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*for (int i = 0; i < count; ++i)
|
/*for (int i = 0; i < count; ++i)
|
||||||
pipes[i].create();
|
pipes[i].create();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user