| 138 | } |
| 139 | |
| 140 | void SchedulerThread::RunLoop() { |
| 141 | while (!shutdown_.WaitFor(MonoDelta::FromMilliseconds(schedule_period_ms_))) { |
| 142 | MonoTime now = MonoTime::Now(); |
| 143 | vector<SchedulerTask> pending_tasks; |
| 144 | { |
| 145 | MutexLock auto_lock(mutex_); |
| 146 | auto upper_it = future_tasks_.upper_bound(now); |
| 147 | for (auto it = future_tasks_.begin(); it != upper_it; it++) { |
| 148 | pending_tasks.emplace_back(std::move(it->second)); |
| 149 | } |
| 150 | future_tasks_.erase(future_tasks_.begin(), upper_it); |
| 151 | } |
| 152 | |
| 153 | for (const auto& task : pending_tasks) { |
| 154 | ThreadPoolToken* token = task.thread_pool_token(); |
| 155 | while (token != nullptr) { |
| 156 | Status s = token->Submit(task.func()); |
| 157 | if (s.ok()) { |
| 158 | break; |
| 159 | } |
| 160 | DCHECK(s.IsServiceUnavailable()) |
| 161 | << Substitute("threadpool token Submit status: $0", s.ToString()); |
| 162 | |
| 163 | if (!token->MaySubmitNewTasks()) { |
| 164 | // threadpool token is Shutdown, skip the task. |
| 165 | break; |
| 166 | } |
| 167 | // If developers use ThreadPoolToken::Schedule(...) too frequent, blocking queue's |
| 168 | // capacity will be full, then retry submit the task again. |
| 169 | VLOG(1) << Substitute("threadpool token Submit status: $0, retry the task", s.ToString()); |
| 170 | SleepFor(MonoDelta::FromMilliseconds(1)); |
| 171 | } |
| 172 | } |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | //////////////////////////////////////////////////////// |
| 177 | // ThreadPoolToken |
no test coverage detected