I'm working on timer queue using concurrent_priority_queue right now..
I implemented basic logic of executing most urgent event in this queue.
Here's my code.
TimerEvent ev{};
while (timer.mLoop)
{
while (timer.mQueue.empty() == false)
{
if (timer.mQueue.try_pop(ev) == false)
continue;
if (ev.Type == EVENT_TYPE::PHYSICS) // Physics event is around 15 ~ 17ms
{
auto now = Clock::now();
std::this_thread::sleep_for(ev.StartTime - now);
timer.mGameServerPtr->PostPhysicsOperation(ev.WorldID);
}
else if (ev.Type == EVENT_TYPE::INVINCIBLE) // This event is 3sec long.
{
auto now = Clock::now();
std::this_thread::sleep_for(ev.StartTime - now); // This is wrong!!
timer.mGameServerPtr->ReleaseInvincibleMode(ev.WorldID);
}
}
std::this_thread::sleep_for(10ms);
}
The problem would be easily solved if there is like front/top method in concurrent_priority_queue.
But there is no such method in class because it isn't thread-safe.
So, I just popped event out of the queue and waited until start time of the event. In this way, I shouldn't have to insert event into queue again.
But problem is that if I have another type of event like EVENT_TYPE::INVINCIBLE, then I shouldn't just use sleep_for because this event is almost 3 second long. While waiting for 3 second, the PHYSICS event will not executed in time.
I can use sleep_for method for PHYSIC event since it is most shortest one to wait.
But I have to re-insert INVINCIBLE event into queue.
How can I optimize this timer without re-insert event into queue again?