| 460 | } |
| 461 | |
| 462 | int bthread_id_about_to_destroy(bthread_id_t id) { |
| 463 | bthread::Id* const meta = address_resource(bthread::get_slot(id)); |
| 464 | if (!meta) { |
| 465 | return EINVAL; |
| 466 | } |
| 467 | const uint32_t id_ver = bthread::get_version(id); |
| 468 | uint32_t* butex = meta->butex; |
| 469 | meta->mutex.lock(); |
| 470 | if (!meta->has_version(id_ver)) { |
| 471 | meta->mutex.unlock(); |
| 472 | return EINVAL; |
| 473 | } |
| 474 | if (*butex == meta->first_ver) { |
| 475 | meta->mutex.unlock(); |
| 476 | LOG(FATAL) << "bthread_id=" << id.value << " is not locked!"; |
| 477 | return EPERM; |
| 478 | } |
| 479 | const bool contended = (*butex == meta->contended_ver()); |
| 480 | *butex = meta->unlockable_ver(); |
| 481 | meta->mutex.unlock(); |
| 482 | if (contended) { |
| 483 | // wake up all waiting lockers. |
| 484 | bthread::butex_wake_except(butex, 0); |
| 485 | } |
| 486 | return 0; |
| 487 | } |
| 488 | |
| 489 | int bthread_id_cancel(bthread_id_t id) { |
| 490 | bthread::Id* const meta = address_resource(bthread::get_slot(id)); |