many changes, need testing

rewrite PIDiagnostics, but not fully testing
change PIQueue to PIDeque
many fixes in PIBaseTransfer, it will be threadsafe and stable


git-svn-id: svn://db.shs.com.ru/pip@187 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
2016-04-12 04:24:57 +00:00
parent 741615b9d3
commit b93205f175
10 changed files with 462 additions and 202 deletions

View File

@@ -0,0 +1,129 @@
#ifndef PIPIPELINETHREAD_H
#define PIPIPELINETHREAD_H
#include "pithread.h"
template <typename T1, typename T2>
class PIPipelineThread : public PIThread
{
PIOBJECT_SUBCLASS(PIPipelineThread, PIThread)
public:
PIPipelineThread() {
cnt = 0;
max_size = 0;
wait_next_pipe = true;
next_overload = false;
}
~PIPipelineThread() {
stop();
if (!waitForFinish(1000)) terminate();
}
template <typename T3>
void connectTo(PIPipelineThread<T2, T3> * next) {
CONNECT2(void, T2, bool *, this, calculated, next, enqueue)
}
EVENT2(calculated, const T2 &, v, bool *, overload)
EVENT_HANDLER1(void, enqueue, const T1 &, v) {enqueue(v, 0);}
EVENT_HANDLER2(void, enqueue, const T1 &, v, bool *, overload) {
mutex.lock();
if (max_size > 0 && in.size() < max_size) {
in.enqueue(v);
if (overload) *overload = false;
} else {
if (overload) *overload = true;
}
mutex.unlock();
}
const ullong * counterPtr() const {return &cnt;}
ullong counter() const {return cnt;}
bool isEmpty() {
bool ret;
mutex.lock();
ret = in.isEmpty();
mutex.unlock();
return ret;
}
int queSize() {
int ret;
mutex.lock();
ret = in.size();
mutex.unlock();
return ret;
}
void clear() {
mutex.lock();
in.clear();
next_overload = false;
mutex.unlock();
}
void stopCalc() {
if (isRunning()) {
stop();
if (!waitForFinish(100)) terminate();
mutex.unlock();
mutex_l.unlock();
}
}
T2 getLast() {
T2 ret;
mutex_l.lock();
ret = last;
mutex_l.unlock();
return ret;
}
uint maxQueSize() {
uint ret;
mutex.lock();
ret = max_size;
mutex.unlock();
return ret;
}
void setMaxQueSize(uint count) {
mutex.lock();
count = max_size;
if (max_size > 0 && in.size() > max_size) in.resize(max_size);
mutex.unlock();
}
bool isWaitNextPipe() {return wait_next_pipe;}
void setWaitNextPipe(bool wait) {wait_next_pipe = wait;}
protected:
virtual T2 calc(const T1 &v, bool &ok) = 0;
private:
void begin() {cnt = 0;}
void run() {
mutex.lock();
if (in.isEmpty()) {
mutex.unlock();
piMSleep(1);
return;
}
if (next_overload) {
calculated(last, &next_overload);
} else {
T1 t = in.dequeue();
bool ok = true;
mutex.unlock();
T2 r = calc(t, ok);
mutex_l.lock();
last = r;
mutex_l.unlock();
cnt++;
if (ok) calculated(r, &next_overload);
}
}
PIQueue<T1> in;
T2 last;
PIMutex mutex;
PIMutex mutex_l;
ullong cnt;
uint max_size;
bool wait_next_pipe;
bool next_overload;
};
#endif // PIPIPELINETHREAD_H