int st_thread_join(_st_thread_t *thread, void **retvalp) { _st_cond_t *term = thread->term; /* Can't join a non-joinable thread */ if (term == NULL) { errno = EINVAL; return -1; } if (_ST_CURRENT_THREAD() == thread) { errno = EDEADLK; return -1; } /* Multiple threads can't wait on the same joinable thread */ if (term->wait_q.next != &term->wait_q) { errno = EINVAL; return -1; } while (thread->state != _ST_ST_ZOMBIE) { if (st_cond_timedwait(term, ST_UTIME_NO_TIMEOUT) != 0) return -1; } if (retvalp) *retvalp = thread->retval; /* * Remove target thread from the zombie queue and make it runnable. * When it gets scheduled later, it will do the clean up. */ thread->state = _ST_ST_RUNNABLE; _ST_DEL_ZOMBIEQ(thread); _ST_ADD_RUNQ(thread); return 0; }
int st_cond_wait(_st_cond_t *cvar) { return st_cond_timedwait(cvar, ST_UTIME_NO_TIMEOUT); }