| 511 | } |
| 512 | |
| 513 | int bthread_id_join(bthread_id_t id) { |
| 514 | const bthread::IdResourceId slot = bthread::get_slot(id); |
| 515 | bthread::Id* const meta = address_resource(slot); |
| 516 | if (!meta) { |
| 517 | // The id is not created yet, this join is definitely wrong. |
| 518 | return EINVAL; |
| 519 | } |
| 520 | const uint32_t id_ver = bthread::get_version(id); |
| 521 | uint32_t* join_butex = meta->join_butex; |
| 522 | while (1) { |
| 523 | meta->mutex.lock(); |
| 524 | const bool has_ver = meta->has_version(id_ver); |
| 525 | const uint32_t expected_ver = *join_butex; |
| 526 | meta->mutex.unlock(); |
| 527 | if (!has_ver) { |
| 528 | break; |
| 529 | } |
| 530 | if (bthread::butex_wait(join_butex, expected_ver, NULL) < 0 && |
| 531 | errno != EWOULDBLOCK && errno != EINTR) { |
| 532 | return errno; |
| 533 | } |
| 534 | } |
| 535 | return 0; |
| 536 | } |
| 537 | |
| 538 | int bthread_id_trylock(bthread_id_t id, void** pdata) { |
| 539 | bthread::Id* const meta = address_resource(bthread::get_slot(id)); |