| @@ -45,61 +45,58 @@ public: | |||
| virtual ~Thread() {} | |||
| }; | |||
| struct ThreadCommand | |||
| struct ThreadStatus | |||
| { | |||
| enum Value | |||
| { | |||
| NOTHING = 0, | |||
| THREAD_STARTED, | |||
| THREAD_STOPPED, | |||
| WORK_TODO, | |||
| WORK_DONE, | |||
| THREAD_STOP, | |||
| MAX | |||
| } | |||
| m_value; | |||
| inline ThreadCommand() : m_value(ThreadCommand::MAX) {} | |||
| inline ThreadCommand(Value v) : m_value(v) {} | |||
| bool operator==(const ThreadCommand& v) { return m_value == v.m_value; } | |||
| inline ThreadStatus() : m_value(ThreadStatus::NOTHING) {} | |||
| inline ThreadStatus(Value v) : m_value(v) {} | |||
| bool operator==(const ThreadStatus& v) { return m_value == v.m_value; } | |||
| }; | |||
| template<typename T1> | |||
| struct JobCommand : public ThreadCommand | |||
| struct ThreadJobType | |||
| { | |||
| inline JobCommand() | |||
| : ThreadCommand(ThreadCommand::WORK_TODO) | |||
| {} | |||
| inline JobCommand(Value v) | |||
| : ThreadCommand(v) | |||
| {} | |||
| enum Value | |||
| { | |||
| NONE = 0, | |||
| WORK_TODO, | |||
| WORK_DONE, | |||
| THREAD_STOP, | |||
| inline JobCommand(T1 const &data) | |||
| : ThreadCommand(ThreadCommand::WORK_TODO), | |||
| m_data(data) | |||
| {} | |||
| MAX | |||
| } | |||
| m_value; | |||
| inline JobCommand(Value v, T1 const &data) | |||
| : ThreadCommand(v), | |||
| m_data(data) | |||
| {} | |||
| inline ThreadJobType() : m_value(ThreadJobType::MAX) {} | |||
| inline ThreadJobType(Value v) : m_value(v) {} | |||
| bool operator==(const ThreadJobType& o) { return m_value == o.m_value; } | |||
| }; | |||
| inline void SetData(T1 const &data) | |||
| { | |||
| m_data = data; | |||
| } | |||
| class ThreadJob | |||
| { | |||
| friend class ThreadManager; | |||
| inline T1 GetData() | |||
| { | |||
| return m_data; | |||
| } | |||
| public: | |||
| ThreadJob() { m_type = ThreadJobType::NONE; } | |||
| ThreadJob(ThreadJobType type) { m_type = type; } | |||
| ThreadJobType GetJobType() { return m_type; } | |||
| void SetJobType(ThreadJobType type) { m_type = type; } | |||
| bool operator==(const ThreadJobType& o) { return GetJobType() == o; } | |||
| protected: | |||
| virtual bool DoWork() { return false; } | |||
| private: | |||
| T1 m_data; | |||
| ThreadJobType m_type; | |||
| }; | |||
| template<typename T1, typename T2> class ThreadManager | |||
| class ThreadManager | |||
| { | |||
| public: | |||
| ThreadManager(int thread_count) | |||
| @@ -123,15 +120,15 @@ public: | |||
| return true; | |||
| } | |||
| bool AddWork(const JobCommand<T1>& job) | |||
| bool AddWork(ThreadJob* job) | |||
| { | |||
| if (m_jobqueue.TryPush(job)) | |||
| return true; | |||
| return false; | |||
| } | |||
| bool FetchResult(Array<JobCommand<T2> >& results) | |||
| bool FetchResult(Array<ThreadJob*>& results) | |||
| { | |||
| JobCommand<T2> result; | |||
| ThreadJob* result; | |||
| while (m_resultqueue.TryPop(result)) | |||
| results << result; | |||
| return results.Count() > 0; | |||
| @@ -140,28 +137,25 @@ public: | |||
| static void *BaseThreadWork(void* data) | |||
| { | |||
| ThreadManager *that = (ThreadManager *)data; | |||
| that->m_spawnqueue.Push(ThreadCommand::THREAD_STARTED); | |||
| that->m_spawnqueue.Push(ThreadStatus::THREAD_STARTED); | |||
| for ( ; ; ) | |||
| { | |||
| JobCommand<T1> job = that->m_jobqueue.Pop(); | |||
| if (job == ThreadCommand::THREAD_STOP) | |||
| ThreadJob* job = that->m_jobqueue.Pop(); | |||
| if (job->GetJobType() == ThreadJobType::THREAD_STOP) | |||
| break; | |||
| else if (job == ThreadCommand::WORK_TODO) | |||
| else if (*job == ThreadJobType::WORK_TODO) | |||
| { | |||
| JobCommand<T2> result(ThreadCommand::WORK_DONE); | |||
| if (that->DoThreadWork(job, result)) | |||
| that->m_resultqueue.Push(result); | |||
| if (job->DoWork()) | |||
| { | |||
| job->SetJobType(ThreadJobType::WORK_DONE); | |||
| that->m_resultqueue.Push(job); | |||
| } | |||
| } | |||
| } | |||
| that->m_donequeue.Push(ThreadCommand::THREAD_STOPPED); | |||
| that->m_donequeue.Push(ThreadStatus::THREAD_STOPPED); | |||
| return NULL; | |||
| } | |||
| virtual bool DoThreadWork(JobCommand<T1>& job, JobCommand<T2>& result) | |||
| { | |||
| return false; | |||
| } | |||
| //Stop the thread | |||
| bool Stop() | |||
| { | |||
| @@ -170,8 +164,9 @@ public: | |||
| /* Signal worker threads for completion and wait for | |||
| * them to quit. */ | |||
| ThreadJob stop_job(ThreadJobType::THREAD_STOP); | |||
| for (int i = 0; i < m_thread_count; i++) | |||
| m_jobqueue.Push(ThreadCommand::THREAD_STOP); | |||
| m_jobqueue.Push(&stop_job); | |||
| for (int i = 0; i < m_thread_count; i++) | |||
| m_donequeue.Pop(); | |||
| @@ -182,9 +177,9 @@ protected: | |||
| /* Worker threads */ | |||
| int m_thread_count; | |||
| Array<Thread*> m_threads; | |||
| Queue<ThreadCommand> m_spawnqueue, m_donequeue; | |||
| Queue<JobCommand<T1> > m_jobqueue; | |||
| Queue<JobCommand<T2> > m_resultqueue; | |||
| Queue<ThreadStatus> m_spawnqueue, m_donequeue; | |||
| Queue<ThreadJob*> m_jobqueue; | |||
| Queue<ThreadJob*> m_resultqueue; | |||
| }; | |||
| #endif | |||