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;
|
|
}
|