| 277 | } |
| 278 | |
| 279 | bool TimerThread::Task::run_and_delete() { |
| 280 | const uint32_t id_version = version_of_task_id(task_id); |
| 281 | uint32_t expected_version = id_version; |
| 282 | // This CAS is rarely contended, should be fast. |
| 283 | if (version.compare_exchange_strong( |
| 284 | expected_version, id_version + 1, butil::memory_order_relaxed)) { |
| 285 | fn(arg); |
| 286 | // The release fence is paired with acquire fence in |
| 287 | // TimerThread::unschedule to make changes of fn(arg) visible. |
| 288 | version.store(id_version + 2, butil::memory_order_release); |
| 289 | butil::return_resource(slot_of_task_id(task_id)); |
| 290 | return true; |
| 291 | } else if (expected_version == id_version + 2) { |
| 292 | // already unscheduled. |
| 293 | butil::return_resource(slot_of_task_id(task_id)); |
| 294 | return false; |
| 295 | } else { |
| 296 | // Impossible. |
| 297 | LOG(ERROR) << "Invalid version=" << expected_version |
| 298 | << ", expecting " << id_version + 2; |
| 299 | return false; |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | bool TimerThread::Task::try_delete() { |
| 304 | const uint32_t id_version = version_of_task_id(task_id); |
no test coverage detected