101 lines
2.1 KiB
C++
101 lines
2.1 KiB
C++
#include "TaskScheduler.h"
|
|
#if defined(__linux) || defined(__linux__)
|
|
#include <signal.h>
|
|
#endif
|
|
|
|
using namespace xop;
|
|
|
|
TaskScheduler::TaskScheduler(int id)
|
|
: id_(id)
|
|
, is_shutdown_(false)
|
|
, wakeup_pipe_(new Pipe())
|
|
, trigger_events_(new xop::RingBuffer<TriggerEvent>(kMaxTriggetEvents))
|
|
{
|
|
static std::once_flag flag;
|
|
std::call_once(flag, [] {
|
|
#if defined(WIN32) || defined(_WIN32)
|
|
WSADATA wsa_data;
|
|
if (WSAStartup(MAKEWORD(2, 2), &wsa_data)) {
|
|
WSACleanup();
|
|
}
|
|
#endif
|
|
});
|
|
|
|
if (wakeup_pipe_->Create()) {
|
|
wakeup_channel_.reset(new Channel(wakeup_pipe_->Read()));
|
|
wakeup_channel_->EnableReading();
|
|
wakeup_channel_->SetReadCallback([this]() { this->Wake(); });
|
|
}
|
|
}
|
|
|
|
TaskScheduler::~TaskScheduler()
|
|
{
|
|
|
|
}
|
|
|
|
void TaskScheduler::Start()
|
|
{
|
|
#if defined(__linux) || defined(__linux__)
|
|
signal(SIGPIPE, SIG_IGN);
|
|
signal(SIGQUIT, SIG_IGN);
|
|
signal(SIGUSR1, SIG_IGN);
|
|
signal(SIGTERM, SIG_IGN);
|
|
signal(SIGKILL, SIG_IGN);
|
|
#endif
|
|
is_shutdown_ = false;
|
|
while (!is_shutdown_) {
|
|
this->HandleTriggerEvent();
|
|
this->timer_queue_.HandleTimerEvent();
|
|
int64_t timeout = this->timer_queue_.GetTimeRemaining();
|
|
this->HandleEvent((int)timeout);
|
|
}
|
|
}
|
|
|
|
void TaskScheduler::Stop()
|
|
{
|
|
is_shutdown_ = true;
|
|
char event = kTriggetEvent;
|
|
wakeup_pipe_->Write(&event, 1);
|
|
}
|
|
|
|
TimerId TaskScheduler::AddTimer(TimerEvent timerEvent, uint32_t msec)
|
|
{
|
|
TimerId id = timer_queue_.AddTimer(timerEvent, msec);
|
|
return id;
|
|
}
|
|
|
|
void TaskScheduler::RemoveTimer(TimerId timerId)
|
|
{
|
|
timer_queue_.RemoveTimer(timerId);
|
|
}
|
|
|
|
bool TaskScheduler::AddTriggerEvent(TriggerEvent callback)
|
|
{
|
|
if (trigger_events_->Size() < kMaxTriggetEvents) {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
char event = kTriggetEvent;
|
|
trigger_events_->Push(std::move(callback));
|
|
wakeup_pipe_->Write(&event, 1);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void TaskScheduler::Wake()
|
|
{
|
|
char event[10] = { 0 };
|
|
while (wakeup_pipe_->Read(event, 10) > 0);
|
|
}
|
|
|
|
void TaskScheduler::HandleTriggerEvent()
|
|
{
|
|
do
|
|
{
|
|
TriggerEvent callback;
|
|
if (trigger_events_->Pop(callback)) {
|
|
callback();
|
|
}
|
|
} while (trigger_events_->Size() > 0);
|
|
}
|