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