Restructure wait_for_thread_etc() to make it easier to follow.
* Avoid needless adding of the death entry if the sem is gone already. * Delete objects as soon as they aren't needed anymore and return early where possible. * Contain the thread == NULL case in its block and return from there as well instead of non-obviously figuring out what happened later. * Pull out the return code asignment. * Minor cleanup.
This commit is contained in:
parent
da329fc012
commit
62bb375688
@ -2465,10 +2465,7 @@ status_t
|
||||
wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
|
||||
status_t *_returnCode)
|
||||
{
|
||||
job_control_entry* freeDeath = NULL;
|
||||
status_t status = B_OK;
|
||||
|
||||
if (id < B_OK)
|
||||
if (id < 0)
|
||||
return B_BAD_THREAD_ID;
|
||||
|
||||
// get the thread, queue our death entry, and fetch the semaphore we have to
|
||||
@ -2480,16 +2477,14 @@ wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
|
||||
if (thread != NULL) {
|
||||
// remember the semaphore we have to wait on and place our death entry
|
||||
exitSem = thread->exit.sem;
|
||||
list_add_link_to_head(&thread->exit.waiters, &death);
|
||||
if (exitSem >= 0)
|
||||
list_add_link_to_head(&thread->exit.waiters, &death);
|
||||
|
||||
thread->UnlockAndReleaseReference();
|
||||
// Note: We mustn't dereference the pointer afterwards, only check
|
||||
// it.
|
||||
}
|
||||
|
||||
thread_death_entry* threadDeathEntry = NULL;
|
||||
|
||||
if (thread == NULL) {
|
||||
if (exitSem < 0)
|
||||
return B_BAD_THREAD_ID;
|
||||
} else {
|
||||
// we couldn't find this thread -- maybe it's already gone, and we'll
|
||||
// find its death entry in our team
|
||||
Team* team = thread_get_current_thread()->team;
|
||||
@ -2498,47 +2493,43 @@ wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
|
||||
// check the child death entries first (i.e. main threads of child
|
||||
// teams)
|
||||
bool deleteEntry;
|
||||
freeDeath = team_get_death_entry(team, id, &deleteEntry);
|
||||
job_control_entry* freeDeath
|
||||
= team_get_death_entry(team, id, &deleteEntry);
|
||||
if (freeDeath != NULL) {
|
||||
death.status = freeDeath->status;
|
||||
if (!deleteEntry)
|
||||
freeDeath = NULL;
|
||||
if (deleteEntry)
|
||||
delete freeDeath;
|
||||
} else {
|
||||
// check the thread death entries of the team (non-main threads)
|
||||
thread_death_entry* threadDeathEntry = NULL;
|
||||
while ((threadDeathEntry = (thread_death_entry*)list_get_next_item(
|
||||
&team->dead_threads, threadDeathEntry)) != NULL) {
|
||||
if (threadDeathEntry->thread == id) {
|
||||
list_remove_item(&team->dead_threads, threadDeathEntry);
|
||||
team->dead_threads_count--;
|
||||
death.status = threadDeathEntry->status;
|
||||
free(threadDeathEntry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (threadDeathEntry == NULL)
|
||||
status = B_BAD_THREAD_ID;
|
||||
return B_BAD_THREAD_ID;
|
||||
}
|
||||
}
|
||||
|
||||
if (thread == NULL && status == B_OK) {
|
||||
// we found the thread's death entry in our team
|
||||
if (_returnCode)
|
||||
*_returnCode = death.status;
|
||||
|
||||
delete freeDeath;
|
||||
free(threadDeathEntry);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// we need to wait for the death of the thread
|
||||
|
||||
if (exitSem < 0)
|
||||
return B_BAD_THREAD_ID;
|
||||
|
||||
resume_thread(id);
|
||||
// make sure we don't wait forever on a suspended thread
|
||||
|
||||
status = acquire_sem_etc(exitSem, 1, flags, timeout);
|
||||
status_t status = acquire_sem_etc(exitSem, 1, flags, timeout);
|
||||
|
||||
if (status == B_OK) {
|
||||
// this should never happen as the thread deletes the semaphore on exit
|
||||
@ -2546,9 +2537,6 @@ wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
|
||||
} else if (status == B_BAD_SEM_ID) {
|
||||
// this is the way the thread normally exits
|
||||
status = B_OK;
|
||||
|
||||
if (_returnCode)
|
||||
*_returnCode = death.status;
|
||||
} else {
|
||||
// We were probably interrupted or the timeout occurred; we need to
|
||||
// remove our death entry now.
|
||||
@ -2563,12 +2551,12 @@ wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
|
||||
// middle of the cleanup.
|
||||
acquire_sem(exitSem);
|
||||
status = B_OK;
|
||||
|
||||
if (_returnCode != NULL)
|
||||
*_returnCode = death.status;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == B_OK && _returnCode != NULL)
|
||||
*_returnCode = death.status;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user