| 114 | } |
| 115 | |
| 116 | ThreadPool(const size_t s) : size_(s), running_(true), pool_(new TSThread[s]) |
| 117 | { |
| 118 | assert(0 < size_); |
| 119 | assert(nullptr != pool_); |
| 120 | for (size_t i = 0; i < size_; ++i) { |
| 121 | pool_[i] = TSThreadCreate( |
| 122 | [](void *d) -> void * { |
| 123 | assert(nullptr != d); |
| 124 | ThreadPool *const self = reinterpret_cast<ThreadPool *>(d); |
| 125 | assert(self->running_); |
| 126 | while (self->running_) { |
| 127 | Callback callback; |
| 128 | { |
| 129 | Lock lock(self->mutex_); |
| 130 | |
| 131 | self->semaphore_.wait(lock, [self] { return !self->queue_.empty() || !self->running_; }); |
| 132 | |
| 133 | if (!self->queue_.empty()) { |
| 134 | callback = self->queue_.front(); |
| 135 | self->queue_.pop_front(); |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | // if a callback was assigned, call it outside of the synchronized scope. |
| 140 | if (callback) { |
| 141 | callback(); |
| 142 | } |
| 143 | } |
| 144 | return nullptr; |
| 145 | }, |
| 146 | this); |
| 147 | assert(nullptr != pool_[i]); |
| 148 | Dbg(dbg_ctl, "Creating thread number %lu (%p)", i, pool_[i]); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | ThreadPool(ThreadPool &) = delete; |
| 153 |
nothing calls this directly
no test coverage detected