diff --git a/servant/libservant/CoroutineScheduler.cpp b/servant/libservant/CoroutineScheduler.cpp index ed21426..6f1b219 100644 --- a/servant/libservant/CoroutineScheduler.cpp +++ b/servant/libservant/CoroutineScheduler.cpp @@ -39,6 +39,9 @@ namespace tars { +#define MAX_WAIT_TIME_MS 1000 +#define MIN_WAIT_TIME_MS 1 + #if TARGET_PLATFORM_WINDOWS // x86_64 @@ -512,19 +515,29 @@ void CoroutineScheduler::run() { while(!_terminal) { - if(CoroutineInfo::CoroutineHeadEmpty(&_avail) && CoroutineInfo::CoroutineHeadEmpty(&_active)) - { - TC_ThreadLock::Lock lock(_monitor); + wakeupbyself(); + + if(!CoroutineInfo::CoroutineHeadEmpty(&_avail)) + { + CoroutineInfo *coro = _avail._next; + + assert(coro != NULL); + + // switchCoro(&_mainCoro, coro); + switchCoro(coro); - if(_activeCoroQueue.size() <= 0) - { - _monitor.timedWait(1000); - } } - wakeupbytimeout(); + //获取第一个即将timeout的剩余时长 + int waitTime = wakeupbytimeout(); - wakeupbyself(); + if(CoroutineInfo::CoroutineHeadEmpty(&_active) && (_activeCoroQueue.size() <= 0)) + { + waitTime = min(max(waitTime, MIN_WAIT_TIME_MS), MAX_WAIT_TIME_MS); + TC_ThreadLock::Lock lock(_monitor); + //限定最多等待时长为waitTime,尽量保证sleep的协程及时被唤醒 + _monitor.timedWait(waitTime); + } wakeup(); @@ -545,17 +558,6 @@ void CoroutineScheduler::run() } - if(!CoroutineInfo::CoroutineHeadEmpty(&_avail)) - { - CoroutineInfo *coro = _avail._next; - - assert(coro != NULL); - - // switchCoro(&_mainCoro, coro); - switchCoro(coro); - - } - if(_usedSize == 0) break; } @@ -711,8 +713,9 @@ void CoroutineScheduler::wakeup() } } -void CoroutineScheduler::wakeupbytimeout() +int CoroutineScheduler::wakeupbytimeout() { + int leftTime = MAX_WAIT_TIME_MS; if(!_terminal) { if(_timeoutCoroId.size() > 0) @@ -722,7 +725,11 @@ void CoroutineScheduler::wakeupbytimeout() { multimap::iterator it = _timeoutCoroId.begin(); - if(it == _timeoutCoroId.end() || it->first > iNow) + if(it == _timeoutCoroId.end()) + break; + + leftTime = it->first - iNow; + if(leftTime > 0) break; CoroutineInfo *coro = _all_coro[it->second]; @@ -736,6 +743,7 @@ void CoroutineScheduler::wakeupbytimeout() } } + return leftTime; } void CoroutineScheduler::terminate() diff --git a/servant/servant/CoroutineScheduler.h b/servant/servant/CoroutineScheduler.h index 06446f7..c46d3cd 100644 --- a/servant/servant/CoroutineScheduler.h +++ b/servant/servant/CoroutineScheduler.h @@ -459,7 +459,7 @@ private: /** * 唤醒休眠的协程 */ - void wakeupbytimeout(); + int wakeupbytimeout(); /** * 放到active的协程链表中