| 275 | } |
| 276 | |
| 277 | int ExecutionQueueBase::stop() { |
| 278 | const uint32_t id_ver = _version_of_id(_this_id); |
| 279 | uint64_t vref = _versioned_ref.load(butil::memory_order_relaxed); |
| 280 | for (;;) { |
| 281 | if (_version_of_vref(vref) != id_ver) { |
| 282 | return EINVAL; |
| 283 | } |
| 284 | // Try to set version=id_ver+1 (to make later address() return NULL), |
| 285 | // retry on fail. |
| 286 | if (_versioned_ref.compare_exchange_strong( |
| 287 | vref, _make_vref(id_ver + 1, _ref_of_vref(vref)), |
| 288 | butil::memory_order_release, |
| 289 | butil::memory_order_relaxed)) { |
| 290 | // Set _stopped to make lattern execute() fail immediately |
| 291 | _stopped.store(true, butil::memory_order_release); |
| 292 | // Deref additionally which is added at creation so that this |
| 293 | // queue's reference will hit 0(recycle) when no one addresses it. |
| 294 | _release_additional_reference(); |
| 295 | // NOTE: This queue may be recycled at this point, don't |
| 296 | // touch anything. |
| 297 | return 0; |
| 298 | } |
| 299 | } |
| 300 | } |
| 301 | |
| 302 | int ExecutionQueueBase::_execute(TaskNode* head, bool high_priority, int* niterated) { |
| 303 | if (head != NULL && head->stop_task) { |
no test coverage detected