| 191 | } |
| 192 | |
| 193 | void streamfx::util::threadpool::threadpool::work(std::shared_ptr<worker_info> wi) |
| 194 | { |
| 195 | std::shared_ptr<streamfx::util::threadpool::task> task{}; |
| 196 | std::lock_guard<std::mutex> lg(wi->lifeline); |
| 197 | |
| 198 | #if defined(D_PLATFORM_WINDOWS) |
| 199 | SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN | THREAD_PRIORITY_BELOW_NORMAL); |
| 200 | SetThreadDescription(GetCurrentThread(), L"StreamFX Worker Thread"); |
| 201 | #elif defined(D_PLATFORM_LINUX) |
| 202 | struct sched_param param; |
| 203 | param.sched_priority = 0; |
| 204 | pthread_setschedparam(pthread_self(), SCHED_IDLE, ¶m); |
| 205 | pthread_setname_np(pthread_self(), "StreamFX Worker Thread"); |
| 206 | #endif |
| 207 | |
| 208 | while (!wi->stop) { |
| 209 | { // Try and acquire new work. |
| 210 | std::unique_lock<std::mutex> ul(_tasks_lock); |
| 211 | |
| 212 | // Is there any work available right now? |
| 213 | if (_tasks.size() == 0) { // If not: |
| 214 | // Block this thread until it is notified of a change. |
| 215 | _tasks_cv.wait_until(ul, std::chrono::time_point(std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(250)), [this, wi]() { return wi->stop || _tasks.size() > 0; }); |
| 216 | } |
| 217 | |
| 218 | // If we were asked to stop, skip everything. |
| 219 | if (wi->stop) { |
| 220 | continue; |
| 221 | } |
| 222 | |
| 223 | // If there is work to be done, take it. |
| 224 | if (_tasks.size() > 0) { |
| 225 | wi->last_work_time = std::chrono::high_resolution_clock::now(); |
| 226 | task = _tasks.front(); |
| 227 | _tasks.pop_front(); |
| 228 | } else if (die(wi)) { // Is the threadpool requesting less threads? |
| 229 | break; |
| 230 | } |
| 231 | } |
| 232 | |
| 233 | if (task) { |
| 234 | task->run(); |
| 235 | task.reset(); |
| 236 | } |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | std::shared_ptr<streamfx::util::threadpool::threadpool> streamfx::util::threadpool::threadpool::instance() |
| 241 | { |