#ifndef _CoWork_CoWork_h #define _CoWork_CoWork_h #include using namespace Upp; namespace MyCoWork { #ifdef _MULTITHREADED class CoWork : NoCopy { struct MJob : Moveable { Callback cb; CoWork *work; }; struct Pool { typedef Pool CLASSNAME; Vector jobs; int waiting_threads; ArrayMap 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 _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