158 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			158 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | // PHZ
 | ||
|  | // 2019-10-18
 | ||
|  | 
 | ||
|  | #include "EventLoop.h"
 | ||
|  | 
 | ||
|  | #if defined(WIN32) || defined(_WIN32) 
 | ||
|  | #include<windows.h>
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if defined(WIN32) || defined(_WIN32) 
 | ||
|  | #pragma comment(lib, "Ws2_32.lib")
 | ||
|  | #pragma comment(lib,"Iphlpapi.lib")
 | ||
|  | #endif 
 | ||
|  | 
 | ||
|  | using namespace xop; | ||
|  | 
 | ||
|  | EventLoop::EventLoop(uint32_t num_threads) | ||
|  | 	: index_(1) | ||
|  | { | ||
|  | 	num_threads_ = 1; | ||
|  | 	if (num_threads > 0) { | ||
|  | 		num_threads_ = num_threads; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	this->Loop(); | ||
|  | } | ||
|  | 
 | ||
|  | EventLoop::~EventLoop() | ||
|  | { | ||
|  | 	this->Quit(); | ||
|  | } | ||
|  | 
 | ||
|  | std::shared_ptr<TaskScheduler> EventLoop::GetTaskScheduler() | ||
|  | { | ||
|  | 	std::lock_guard<std::mutex> locker(mutex_); | ||
|  | 	if (task_schedulers_.size() == 1) { | ||
|  | 		return task_schedulers_.at(0); | ||
|  | 	} | ||
|  | 	else { | ||
|  | 		auto task_scheduler = task_schedulers_.at(index_); | ||
|  | 		index_++; | ||
|  | 		if (index_ >= task_schedulers_.size()) { | ||
|  | 			index_ = 1; | ||
|  | 		}		 | ||
|  | 		return task_scheduler; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return nullptr; | ||
|  | } | ||
|  | 
 | ||
|  | void EventLoop::Loop() | ||
|  | { | ||
|  | 	std::lock_guard<std::mutex> locker(mutex_); | ||
|  | 
 | ||
|  | 	if (!task_schedulers_.empty()) { | ||
|  | 		return ; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for (uint32_t n = 0; n < num_threads_; n++)  | ||
|  | 	{ | ||
|  | #if defined(__linux) || defined(__linux__) 
 | ||
|  | 		std::shared_ptr<TaskScheduler> task_scheduler_ptr(new EpollTaskScheduler(n)); | ||
|  | #elif defined(WIN32) || defined(_WIN32) 
 | ||
|  | 		std::shared_ptr<TaskScheduler> task_scheduler_ptr(new SelectTaskScheduler(n)); | ||
|  | #endif
 | ||
|  | 		task_schedulers_.push_back(task_scheduler_ptr); | ||
|  | 		std::shared_ptr<std::thread> thread(new std::thread(&TaskScheduler::Start, task_scheduler_ptr.get())); | ||
|  | 		thread->native_handle(); | ||
|  | 		threads_.push_back(thread); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	const int priority = TASK_SCHEDULER_PRIORITY_REALTIME; | ||
|  | 
 | ||
|  | 	for (auto iter : threads_)  | ||
|  | 	{ | ||
|  | #if defined(__linux) || defined(__linux__) 
 | ||
|  | 
 | ||
|  | #elif defined(WIN32) || defined(_WIN32) 
 | ||
|  | 		switch (priority)  | ||
|  | 		{ | ||
|  | 		case TASK_SCHEDULER_PRIORITY_LOW: | ||
|  | 			SetThreadPriority(iter->native_handle(), THREAD_PRIORITY_BELOW_NORMAL); | ||
|  | 			break; | ||
|  | 		case TASK_SCHEDULER_PRIORITY_NORMAL: | ||
|  | 			SetThreadPriority(iter->native_handle(), THREAD_PRIORITY_NORMAL); | ||
|  | 			break; | ||
|  | 		case TASK_SCHEDULER_PRIORITYO_HIGH: | ||
|  | 			SetThreadPriority(iter->native_handle(), THREAD_PRIORITY_ABOVE_NORMAL); | ||
|  | 			break; | ||
|  | 		case TASK_SCHEDULER_PRIORITY_HIGHEST: | ||
|  | 			SetThreadPriority(iter->native_handle(), THREAD_PRIORITY_HIGHEST); | ||
|  | 			break; | ||
|  | 		case TASK_SCHEDULER_PRIORITY_REALTIME: | ||
|  | 			SetThreadPriority(iter->native_handle(), THREAD_PRIORITY_TIME_CRITICAL); | ||
|  | 			break; | ||
|  | 		} | ||
|  | #endif
 | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void EventLoop::Quit() | ||
|  | { | ||
|  | 	std::lock_guard<std::mutex> locker(mutex_); | ||
|  | 
 | ||
|  | 	for (auto iter : task_schedulers_) { | ||
|  | 		iter->Stop(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for (auto iter : threads_) { | ||
|  | 		iter->join(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	task_schedulers_.clear(); | ||
|  | 	threads_.clear(); | ||
|  | } | ||
|  | 	 | ||
|  | void EventLoop::UpdateChannel(ChannelPtr channel) | ||
|  | { | ||
|  | 	std::lock_guard<std::mutex> locker(mutex_); | ||
|  | 	if (task_schedulers_.size() > 0) { | ||
|  | 		task_schedulers_[0]->UpdateChannel(channel); | ||
|  | 	}	 | ||
|  | } | ||
|  | 
 | ||
|  | void EventLoop::RemoveChannel(ChannelPtr& channel) | ||
|  | { | ||
|  | 	std::lock_guard<std::mutex> locker(mutex_); | ||
|  | 	if (task_schedulers_.size() > 0) { | ||
|  | 		task_schedulers_[0]->RemoveChannel(channel); | ||
|  | 	}	 | ||
|  | } | ||
|  | 
 | ||
|  | TimerId EventLoop::AddTimer(TimerEvent timerEvent, uint32_t msec) | ||
|  | { | ||
|  | 	std::lock_guard<std::mutex> locker(mutex_); | ||
|  | 	if (task_schedulers_.size() > 0) { | ||
|  | 		return task_schedulers_[0]->AddTimer(timerEvent, msec); | ||
|  | 	} | ||
|  | 	return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void EventLoop::RemoveTimer(TimerId timerId) | ||
|  | { | ||
|  | 	std::lock_guard<std::mutex> locker(mutex_); | ||
|  | 	if (task_schedulers_.size() > 0) { | ||
|  | 		task_schedulers_[0]->RemoveTimer(timerId); | ||
|  | 	}	 | ||
|  | } | ||
|  | 
 | ||
|  | bool EventLoop::AddTriggerEvent(TriggerEvent callback) | ||
|  | {    | ||
|  | 	std::lock_guard<std::mutex> locker(mutex_); | ||
|  | 	if (task_schedulers_.size() > 0) { | ||
|  | 		return task_schedulers_[0]->AddTriggerEvent(callback); | ||
|  | 	} | ||
|  | 	return false; | ||
|  | } |