Blob Blame Raw
#ifndef THREADPOOL_H
#define THREADPOOL_H


#include <list>
#include <deque>
#include <mutex>
#include <thread>
#include <functional>
#include <condition_variable>


#include "common.h"


typedef Shared TaskOwner;


class ThreadPool {
public:
	typedef unsigned long long TaskId;
	typedef std::function<void()> Task;
	
	struct TaskDesc {
		TaskId id;
		TaskOwner::Handle::Weak owner;
		Task task;
		
		inline TaskDesc():
			id(), owner(), task(nullptr) { }
		inline TaskDesc(TaskId id, const TaskOwner::Handle::Weak &owner, const Task &task):
			id(id), owner(owner), task(task) { }
	};

	struct Thread {
		std::thread *thread;
		std::condition_variable condition;
		TaskId taskId;
		TaskOwner::Handle taskOwner;
		bool stopping;
		
		inline Thread():
			thread(), taskId(), taskOwner(), stopping() { }
	};
	
	typedef std::list<Thread> ThreadList;
	typedef std::deque<TaskDesc> Queue;
	
private:
	std::mutex mutexStartStop;
	std::mutex mutex;
	std::condition_variable condition;
	ThreadList threads;
	Queue queue;
	TaskId lastId;
	
	void threadRun(Thread &thread);
	
public:
	ThreadPool();
	~ThreadPool();
	
	TaskId enqueue(const Task &task, const TaskOwner::Handle &owner = nullptr);
	int cancelById(TaskId id, bool wait = true);
	int cancelByOwner(const TaskOwner::Handle &owner, bool wait = true);
	int cancelAll(bool wait = true);
	
	void start(int count, bool cancelAllTasks = false);
	inline void stop(bool cancelAllTasks = false)
		{ start(0, cancelAllTasks); }
};


#endif