| 150 | using time_point = std::chrono::steady_clock::time_point; |
| 151 | |
| 152 | void run() |
| 153 | { |
| 154 | while (true) |
| 155 | { |
| 156 | while (command_type* op = command_queue_.pop_front()) |
| 157 | { |
| 158 | if (op->command_ == command_type::command_type::schedule) |
| 159 | { |
| 160 | auto* task = static_cast<task_type*>(op); |
| 161 | task->when_ = _time_thrd_sched::when_type{task->time_point_, submission_counter_++}; |
| 162 | heap_.insert(task); |
| 163 | } |
| 164 | else |
| 165 | { |
| 166 | STDEXEC_ASSERT(op->command_ == command_type::command_type::stop); |
| 167 | auto* stop_op = static_cast<stop_type*>(op); |
| 168 | if (heap_.erase(stop_op->target_)) |
| 169 | { |
| 170 | stop_op->target_->set_stopped_(stop_op->target_); |
| 171 | } |
| 172 | stop_op->set_value_(stop_op); |
| 173 | } |
| 174 | } |
| 175 | time_point now = std::chrono::steady_clock::now(); |
| 176 | task_type* op = heap_.front(); |
| 177 | while (op && op->time_point_ <= now) |
| 178 | { |
| 179 | heap_.pop_front(); |
| 180 | op->set_value_(op); |
| 181 | op = heap_.front(); |
| 182 | } |
| 183 | time_point deadline = op ? op->time_point_ : now + std::chrono::seconds(2); |
| 184 | std::unique_lock lock{ready_mutex_}; |
| 185 | cv_.wait_until(lock, deadline, [this] { return ready_ || stop_requested_; }); |
| 186 | bool stop_requested = stop_requested_; |
| 187 | ready_ = false; |
| 188 | lock.unlock(); |
| 189 | if (stop_requested) |
| 190 | { |
| 191 | std::ptrdiff_t expected = 0; |
| 192 | while ( |
| 193 | !n_submissions_in_flight_.compare_exchange_weak(expected, |
| 194 | context_closed, |
| 195 | STDEXEC::__std::memory_order_relaxed)) |
| 196 | { |
| 197 | STDEXEC::__spin_loop_pause(); |
| 198 | expected = 0; |
| 199 | } |
| 200 | op = heap_.front(); |
| 201 | while (op) |
| 202 | { |
| 203 | heap_.pop_front(); |
| 204 | op->set_stopped_(op); |
| 205 | op = heap_.front(); |
| 206 | } |
| 207 | break; |
| 208 | } |
| 209 | } |
nothing calls this directly
no test coverage detected