- if (timo)
- thread_set_timer(timo, NSEC_PER_SEC / hz);
-
- /*
- * We start our timeout
- * before calling CURSIG, as we could stop there, and a wakeup
- * or a SIGCONT (or both) could occur while we were stopped.
- * A SIGCONT would cause us to be marked as SSLEEP
- * without resuming us, thus we must be ready for sleep
- * when CURSIG is called. If the wakeup happens while we're
- * stopped, p->p_wchan will be 0 upon return from CURSIG.
- */
- if (catch) {
- unix_master();
- if (SHOULDissignal(p,ut)) {
- if (sig = CURSIG(p)) {
- clear_wait(thread, THREAD_INTERRUPTED);
- /* if SIGTTOU or SIGTTIN then block till SIGCONT */
- if (sigttblock && ((sig == SIGTTOU) || (sig == SIGTTIN))) {
- p->p_flag |= P_TTYSLEEP;
- /* reset signal bits */
- clear_sigbits(p, sig);
- assert_wait(&p->p_siglist, THREAD_ABORTSAFE);
- /* assert wait can block and SIGCONT should be checked */
- if (p->p_flag & P_TTYSLEEP)
- thread_block(0);
- /* return with success */
- error = 0;
+
+ /* set wait message & channel */
+ ut->uu_wchan = chan;
+ ut->uu_wmesg = wmsg ? wmsg : "unknown";
+
+ if (mtx != NULL && chan != NULL && (thread_continue_t)continuation == THREAD_CONTINUE_NULL) {
+ int flags;
+
+ if (dropmutex) {
+ flags = LCK_SLEEP_UNLOCK;
+ } else {
+ flags = LCK_SLEEP_DEFAULT;
+ }
+
+ if (spinmutex) {
+ flags |= LCK_SLEEP_SPIN;
+ }
+
+ if (abstime) {
+ wait_result = lck_mtx_sleep_deadline(mtx, flags, chan, catch, abstime);
+ } else {
+ wait_result = lck_mtx_sleep(mtx, flags, chan, catch);
+ }
+ } else {
+ if (chan != NULL) {
+ assert_wait_deadline(chan, catch, abstime);
+ }
+ if (mtx) {
+ lck_mtx_unlock(mtx);
+ }
+
+ if (catch == THREAD_ABORTSAFE) {
+ if (SHOULDissignal(p, ut)) {
+ if ((sig = CURSIG(p)) != 0) {
+ if (clear_wait(self, THREAD_INTERRUPTED) == KERN_FAILURE) {
+ goto block;
+ }
+ if (p->p_sigacts->ps_sigintr & sigmask(sig)) {
+ error = EINTR;
+ } else {
+ error = ERESTART;
+ }
+ if (mtx && !dropmutex) {
+ if (spinmutex) {
+ lck_mtx_lock_spin(mtx);
+ } else {
+ lck_mtx_lock(mtx);
+ }
+ }