ultimatepp/bazaar/CoWork/CoWork.h

85 lines
1.8 KiB
C++

#ifndef _CoWork_CoWork_h
#define _CoWork_CoWork_h
#include <Core/Core.h>
using namespace Upp;
namespace MyCoWork
{
#ifdef _MULTITHREADED
class CoWork : NoCopy {
struct MJob : Moveable<MJob> {
Callback cb;
CoWork *work;
};
struct Pool {
typedef Pool CLASSNAME;
Vector<MJob> jobs;
int waiting_threads;
ArrayMap<unsigned, Thread> threads;
CriticalSection lock;
Semaphore waitforjob;
Pool(int threadnr = -1);
~Pool();
void AddThread(int count = 1);
void KillThread(int count = 1, bool waitone = false);
bool DoJob();
void ThreadRun(unsigned tno);
};
friend struct Pool;
One<Pool> _opool; //local pool, needs to be here, before _pool, to be initialized before
static Pool& pool(); //global pool, switch in CoWork()
Pool & _pool; //this ref is actually used, set depending on threadnr
Semaphore waitforfinish;
int todo;
public:
void Do(Callback cb);
CoWork& operator&(Callback cb) { Do(cb); return *this; }
int GetThreadCount() const { return _pool.threads.GetCount(); }
int GetThreadCount() { _pool.lock.Enter(); int c = _pool.threads.GetCount(); _pool.lock.Leave(); return c; }
void AddThread(int count = 1) { ASSERT(&_pool != &pool()); _pool.AddThread(count); }
void KillThread(int count = 1, bool waitone = false) { ASSERT(&_pool != &pool()); _pool.KillThread(count, waitone); }
void Finish();
CoWork(int threadnr = -1);
~CoWork();
};
#else
class CoWork : NoCopy {
public:
void Do(Callback cb) { cb(); }
CoWork& operator&(Callback cb) { cb(); return *this; }
void Finish() {}
CoWork(int threadnr = -1) {}
};
#endif
class WorkQueue : public CoWork
{
public:
WorkQueue()
: CoWork(1)
{}
};
} //namespace
#endif