diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index a0eaaec2a10..d3504c0dda7 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -397,7 +397,6 @@ struct task_join_s { sq_entry_t entry; /* Implements link list */ pid_t pid; /* Includes pid */ - bool detached; /* true: pthread_detached'ed */ pthread_addr_t exit_value; /* Returned data */ }; diff --git a/sched/pthread/pthread_completejoin.c b/sched/pthread/pthread_completejoin.c index bcc3637c850..e7c60e0d8a5 100644 --- a/sched/pthread/pthread_completejoin.c +++ b/sched/pthread/pthread_completejoin.c @@ -95,12 +95,12 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value) nxsem_post(&wtcb->join_sem); } } - else if (!sq_is_singular(&tcb->group->tg_members)) + else if (!sq_is_singular(&tcb->group->tg_members) && + (tcb->flags & TCB_FLAG_DETACHED) == 0) { ret = pthread_findjoininfo(tcb->group, pid, &join, true); if (ret == OK) { - join->detached = !!(tcb->flags & TCB_FLAG_DETACHED); join->exit_value = exit_value; } } diff --git a/sched/pthread/pthread_detach.c b/sched/pthread/pthread_detach.c index 48c6d09f2d2..9eac0625ded 100644 --- a/sched/pthread/pthread_detach.c +++ b/sched/pthread/pthread_detach.c @@ -71,16 +71,14 @@ int pthread_detach(pthread_t thread) nxrmutex_lock(&group->tg_joinlock); tcb = nxsched_get_tcb((pid_t)thread); - if (tcb == NULL) + if (tcb == NULL || (tcb->flags & TCB_FLAG_JOIN_COMPLETED) != 0) { - /* If tcb has been destroyed, update the pending join - * status in the group. - */ + /* Destroy the join information */ ret = pthread_findjoininfo(group, (pid_t)thread, &join, false); if (ret == OK) { - join->detached = true; + pthread_destroyjoin(group, join); } else { diff --git a/sched/pthread/pthread_join.c b/sched/pthread/pthread_join.c index 27422008bf3..6094fc4735f 100644 --- a/sched/pthread/pthread_join.c +++ b/sched/pthread/pthread_join.c @@ -89,26 +89,14 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) ret = pthread_findjoininfo(group, (pid_t)thread, &join, false); if (ret == OK) { - /* If the task is terminated, maintain the same behavior as Linux: - * 1. Join detached task will always return EINVAL. - * 2. Other threads will destroy the join information after - * obtain the exit value, ESRCH will return if calling - * pthread_join() again - */ + /* Destroy the join information after obtain the exit value */ - if (join->detached) + if (pexit_value != NULL) { - ret = EINVAL; + *pexit_value = join->exit_value; } - else - { - if (pexit_value != NULL) - { - *pexit_value = join->exit_value; - } - pthread_destroyjoin(group, join); - } + pthread_destroyjoin(group, join); } else {