1 #ifndef _CoWork_CoWork_h 2 #define _CoWork_CoWork_h 3 4 #include <Core/Core.h> 5 6 using namespace Upp; 7 8 namespace MyCoWork 9 { 10 11 #ifdef _MULTITHREADED 12 13 class CoWork : NoCopy { 14 15 struct MJob : Moveable<MJob> { 16 Callback cb; 17 CoWork *work; 18 }; 19 20 struct Pool { 21 typedef Pool CLASSNAME; 22 Vector<MJob> jobs; 23 int waiting_threads; 24 ArrayMap<unsigned, Thread> threads; 25 26 CriticalSection lock; 27 Semaphore waitforjob; 28 29 Pool(int threadnr = -1); 30 ~Pool(); 31 32 void AddThread(int count = 1); 33 void KillThread(int count = 1, bool waitone = false); 34 35 bool DoJob(); 36 void ThreadRun(unsigned tno); 37 }; 38 39 friend struct Pool; 40 41 One<Pool> _opool; //local pool, needs to be here, before _pool, to be initialized before 42 static Pool& pool(); //global pool, switch in CoWork() 43 Pool & _pool; //this ref is actually used, set depending on threadnr 44 45 Semaphore waitforfinish; 46 int todo; 47 48 public: 49 void Do(Callback cb); 50 CoWork& operator&(Callback cb) { Do(cb); return *this; } 51 GetThreadCount()52 int GetThreadCount() const { return _pool.threads.GetCount(); } GetThreadCount()53 int GetThreadCount() { _pool.lock.Enter(); int c = _pool.threads.GetCount(); _pool.lock.Leave(); return c; } 54 void AddThread(int count = 1) { ASSERT(&_pool != &pool()); _pool.AddThread(count); } 55 void KillThread(int count = 1, bool waitone = false) { ASSERT(&_pool != &pool()); _pool.KillThread(count, waitone); } 56 57 void Finish(); 58 59 CoWork(int threadnr = -1); 60 ~CoWork(); 61 }; 62 63 #else 64 65 class CoWork : NoCopy { 66 public: 67 void Do(Callback cb) { cb(); } 68 CoWork& operator&(Callback cb) { cb(); return *this; } 69 void Finish() {} 70 CoWork(int threadnr = -1) {} 71 }; 72 73 #endif 74 75 class WorkQueue : public CoWork 76 { 77 public: WorkQueue()78 WorkQueue() 79 : CoWork(1) 80 {} 81 }; 82 83 } //namespace 84 85 #endif 86