* @brief Waits for the specified thread to terminate and retrieves its exit status. * * The `pthread_join` function blocks the calling thread until the specified thread terminates. * If the specified thread has already terminated, it returns immediately. The exit status of * the terminated thread can optionally be retrieved via the `value_ptr` parameter. * * @param[in] thread * The thread
| 602 | * @see pthread_create, pthread_exit, pthread_detach |
| 603 | */ |
| 604 | int pthread_join(pthread_t thread, void **value_ptr) |
| 605 | { |
| 606 | _pthread_data_t *ptd; |
| 607 | rt_err_t result; |
| 608 | |
| 609 | ptd = _pthread_get_data(thread); |
| 610 | |
| 611 | if (ptd == RT_NULL) |
| 612 | { |
| 613 | return EINVAL; /* invalid pthread id */ |
| 614 | } |
| 615 | |
| 616 | if (ptd->tid == rt_thread_self()) |
| 617 | { |
| 618 | /* join self */ |
| 619 | return EDEADLK; |
| 620 | } |
| 621 | |
| 622 | if (ptd->attr.detachstate == PTHREAD_CREATE_DETACHED) |
| 623 | { |
| 624 | return EINVAL; /* join on a detached pthread */ |
| 625 | } |
| 626 | |
| 627 | result = rt_sem_take(ptd->joinable_sem, RT_WAITING_FOREVER); |
| 628 | if (result == RT_EOK) |
| 629 | { |
| 630 | /* get return value */ |
| 631 | if (value_ptr != RT_NULL) |
| 632 | *value_ptr = ptd->return_value; |
| 633 | |
| 634 | /* destroy this pthread */ |
| 635 | _pthread_data_destroy(ptd); |
| 636 | } |
| 637 | else |
| 638 | { |
| 639 | return ESRCH; |
| 640 | } |
| 641 | |
| 642 | return 0; |
| 643 | } |
| 644 | RTM_EXPORT(pthread_join); |
| 645 | |
| 646 | /** |
no test coverage detected