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:
129
src/thread/pipipelinethread.h
Normal file
129
src/thread/pipipelinethread.h
Normal 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
|
||||
Reference in New Issue
Block a user