| 125 | } |
| 126 | |
| 127 | void ThreadPool::WorkRoutine(ThreadContext* context) { |
| 128 | ThreadContext::TaskList tasks; |
| 129 | for (;;) { |
| 130 | bool continued = context->GetPendingTask(&tasks); |
| 131 | ThreadContext::TaskList::iterator i; |
| 132 | for (i = tasks.begin(); i != tasks.end(); ++i) { |
| 133 | if (i->callback) { |
| 134 | i->callback->Run(); |
| 135 | i->callback = NULL; |
| 136 | } else { |
| 137 | i->function(); |
| 138 | i->function = NULL; |
| 139 | } |
| 140 | } |
| 141 | if (!continued) |
| 142 | break; |
| 143 | } |
| 144 | |
| 145 | // Clear free_tasks list |
| 146 | // Exiting, so no other context will operate this list. |
| 147 | context->free_tasks.splice(tasks); |
| 148 | while (!context->free_tasks.empty()) { |
| 149 | Task* task = &context->free_tasks.front(); |
| 150 | context->free_tasks.pop_front(); |
| 151 | delete task; |
| 152 | } |
| 153 | MutexLocker locker(&m_exit_lock); |
| 154 | if (--m_num_busy_threads == 0) |
| 155 | m_exit_cond.Signal(); |
| 156 | } |
| 157 | |
| 158 | bool ThreadPool::AnyTaskPending() const { |
| 159 | for (size_t i = 0; i < m_num_threads; ++i) { |