mirror of
https://github.com/caozhiyi/CppNet.git
synced 2026-01-19 00:05:14 +08:00
115 lines
3.5 KiB
C++
115 lines
3.5 KiB
C++
#ifndef HEADER_BASE_RUNNABLEALONETASKLISTWITHPOST
|
|
#define HEADER_BASE_RUNNABLEALONETASKLISTWITHPOST
|
|
|
|
#include <map>
|
|
#include <mutex>
|
|
|
|
#include "Runnable.h"
|
|
#include "TaskQueue.h"
|
|
|
|
namespace base {
|
|
|
|
typedef std::function<void()> Task;
|
|
|
|
class CRunnableAloneTaskListWithPost : public CRunnable {
|
|
public:
|
|
CRunnableAloneTaskListWithPost() {}
|
|
virtual ~CRunnableAloneTaskListWithPost() {}
|
|
|
|
int GetTaskListSize() {
|
|
return _task_list.Size();
|
|
}
|
|
|
|
virtual void Start();
|
|
virtual void Stop();
|
|
|
|
//post task
|
|
void Push(const Task&& func) {
|
|
_task_list.Push(func);
|
|
}
|
|
void Push(const Task& func) {
|
|
_task_list.Push(func);
|
|
}
|
|
|
|
//TO DO
|
|
virtual void Run();
|
|
|
|
std::thread::id GetId()const { return _id; }
|
|
|
|
//post task to the thread
|
|
static bool PostTask(const std::thread::id& thread_id, const Task& func);
|
|
|
|
private:
|
|
Task _Pop() {
|
|
return std::move(_task_list.Pop());
|
|
}
|
|
|
|
CRunnableAloneTaskListWithPost(const CRunnableAloneTaskListWithPost&) = delete;
|
|
CRunnableAloneTaskListWithPost& operator=(const CRunnableAloneTaskListWithPost&) = delete;
|
|
|
|
private:
|
|
CTaskQueue<Task> _task_list;
|
|
std::thread::id _id;
|
|
|
|
static std::mutex _map_mutex;
|
|
static std::map<std::thread::id, CRunnableAloneTaskListWithPost*> _runnable_map;
|
|
};
|
|
|
|
std::mutex CRunnableAloneTaskListWithPost::_map_mutex;
|
|
std::map<std::thread::id, CRunnableAloneTaskListWithPost*> CRunnableAloneTaskListWithPost::_runnable_map;
|
|
|
|
void CRunnableAloneTaskListWithPost::Start() {
|
|
_stop = false;
|
|
if (!_pthread) {
|
|
_pthread = std::shared_ptr<std::thread>(new std::thread(std::bind(&CRunnableAloneTaskListWithPost::Run, this)));
|
|
}
|
|
|
|
Push([this]() {
|
|
std::unique_lock<std::mutex> lock(_map_mutex);
|
|
auto iter = _runnable_map.find(std::this_thread::get_id());
|
|
if (iter == _runnable_map.end()) {
|
|
_runnable_map[std::this_thread::get_id()] = this;
|
|
_id = std::this_thread::get_id();
|
|
}
|
|
});
|
|
}
|
|
|
|
void CRunnableAloneTaskListWithPost::Stop() {
|
|
Push([this]() {
|
|
{
|
|
std::unique_lock<std::mutex> lock(_map_mutex);
|
|
auto iter = _runnable_map.find(std::this_thread::get_id());
|
|
if (iter != _runnable_map.end()) {
|
|
_runnable_map.erase(iter);
|
|
}
|
|
}
|
|
Push(nullptr);
|
|
_stop = true;
|
|
});
|
|
}
|
|
|
|
bool CRunnableAloneTaskListWithPost::PostTask(const std::thread::id& thread_id, const Task& func) {
|
|
std::unique_lock<std::mutex> lock(_map_mutex);
|
|
auto iter = _runnable_map.find(thread_id);
|
|
if (iter != _runnable_map.end()) {
|
|
if (iter->second) {
|
|
iter->second->Push(func);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CRunnableAloneTaskListWithPost::Run() {
|
|
while (!_stop) {
|
|
auto t = _Pop();
|
|
if (t) {
|
|
t();
|
|
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif |