79 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| #include "Timer.h"
 | |
| #include <iostream>
 | |
| 
 | |
| using namespace xop;
 | |
| using namespace std;
 | |
| using namespace std::chrono;
 | |
| 
 | |
| TimerId TimerQueue::AddTimer(const TimerEvent& event, uint32_t ms)
 | |
| {    
 | |
| 	std::lock_guard<std::mutex> locker(mutex_);
 | |
| 
 | |
| 	int64_t timeout = GetTimeNow();
 | |
| 	TimerId timer_id = ++last_timer_id_;
 | |
| 
 | |
| 	auto timer = make_shared<Timer>(event, ms);	
 | |
| 	timer->SetNextTimeout(timeout);
 | |
| 	timers_.emplace(timer_id, timer);
 | |
| 	events_.emplace(std::pair<int64_t, TimerId>(timeout + ms, timer_id), std::move(timer));
 | |
| 	return timer_id;
 | |
| }
 | |
| 
 | |
| void TimerQueue::RemoveTimer(TimerId timerId)
 | |
| {
 | |
| 	std::lock_guard<std::mutex> locker(mutex_);
 | |
| 
 | |
| 	auto iter = timers_.find(timerId);
 | |
| 	if (iter != timers_.end()) {
 | |
| 		int64_t timeout = iter->second->getNextTimeout();
 | |
| 		events_.erase(std::pair<int64_t, TimerId>(timeout, timerId));
 | |
| 		timers_.erase(timerId);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int64_t TimerQueue::GetTimeNow()
 | |
| {	
 | |
| 	auto time_point = steady_clock::now();	
 | |
| 	return duration_cast<milliseconds>(time_point.time_since_epoch()).count();
 | |
| }
 | |
| 
 | |
| int64_t TimerQueue::GetTimeRemaining()
 | |
| {	
 | |
| 	std::lock_guard<std::mutex> locker(mutex_);
 | |
| 
 | |
| 	if (timers_.empty()) {
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int64_t msec = events_.begin()->first.first - GetTimeNow();
 | |
| 	if (msec < 0) {
 | |
| 		msec = 0;
 | |
| 	}
 | |
| 
 | |
| 	return msec;
 | |
| }
 | |
| 
 | |
| void TimerQueue::HandleTimerEvent()
 | |
| {
 | |
| 	if(!timers_.empty()) {
 | |
| 		std::lock_guard<std::mutex> locker(mutex_);
 | |
| 		int64_t timePoint = GetTimeNow();
 | |
| 		while(!timers_.empty() && events_.begin()->first.first<=timePoint)
 | |
| 		{	
 | |
| 			TimerId timerId = events_.begin()->first.second;
 | |
| 			bool flag = events_.begin()->second->event_callback_();
 | |
| 			if(flag == true) {
 | |
| 				events_.begin()->second->SetNextTimeout(timePoint);
 | |
| 				auto timerPtr = std::move(events_.begin()->second);
 | |
| 				events_.erase(events_.begin());
 | |
| 				events_.emplace(std::pair<int64_t, TimerId>(timerPtr->getNextTimeout(), timerId), timerPtr);
 | |
| 			}
 | |
| 			else {		
 | |
| 				events_.erase(events_.begin());
 | |
| 				timers_.erase(timerId);				
 | |
| 			}
 | |
| 		}	
 | |
| 	}
 | |
| }
 | |
| 
 |