Date: Sat, 20 Nov 2004 04:40:03 GMT From: David Xu <davidxu@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 65514 for review Message-ID: <200411200440.iAK4e3xD006302@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=65514 Change 65514 by davidxu@davidxu_alona on 2004/11/20 04:39:52 let kernel do signal work. Affected files ... .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigaltstack.c#2 edit .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigmask.c#2 edit .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigpending.c#2 edit .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigsuspend.c#2 edit .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigwait.c#2 edit Differences ... ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigaltstack.c#2 (text+ko) ==== @@ -34,74 +34,7 @@ __weak_reference(_sigaltstack, sigaltstack); int -_sigaltstack(stack_t *_ss, stack_t *_oss) +_sigaltstack(stack_t *ss, stack_t *oss) { - struct pthread *curthread = _get_curthread(); - stack_t ss, oss; - int oonstack, errsave, ret; - kse_critical_t crit; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - crit = _kse_critical_enter(); - ret = __sys_sigaltstack(_ss, _oss); - errsave = errno; - /* Get a copy */ - if (ret == 0 && _ss != NULL) - curthread->sigstk = *_ss; - _kse_critical_leave(crit); - errno = errsave; - return (ret); - } - - if (_ss) - ss = *_ss; - if (_oss) - oss = *_oss; - - /* Should get and set stack in atomic way */ - crit = _kse_critical_enter(); - oonstack = _thr_sigonstack(&ss); - if (_oss != NULL) { - oss = curthread->sigstk; - oss.ss_flags = (curthread->sigstk.ss_flags & SS_DISABLE) - ? SS_DISABLE : ((oonstack) ? SS_ONSTACK : 0); - } - - if (_ss != NULL) { - if (oonstack) { - _kse_critical_leave(crit); - errno = EPERM; - return (-1); - } - if ((ss.ss_flags & ~SS_DISABLE) != 0) { - _kse_critical_leave(crit); - errno = EINVAL; - return (-1); - } - if (!(ss.ss_flags & SS_DISABLE)) { - if (ss.ss_size < MINSIGSTKSZ) { - _kse_critical_leave(crit); - errno = ENOMEM; - return (-1); - } - curthread->sigstk = ss; - } else { - curthread->sigstk.ss_flags |= SS_DISABLE; - } - } - _kse_critical_leave(crit); - if (_oss != NULL) - *_oss = oss; - return (0); + return (__sys_sigaltstack(ss, oss)); } - -int -_thr_sigonstack(void *sp) -{ - struct pthread *curthread = _get_curthread(); - - return ((curthread->sigstk.ss_flags & SS_DISABLE) == 0 ? - (((size_t)sp - (size_t)curthread->sigstk.ss_sp) < curthread->sigstk.ss_size) - : 0); -} - ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigmask.c#2 (text+ko) ==== @@ -46,68 +46,12 @@ _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) { struct pthread *curthread = _get_curthread(); - sigset_t oldset, newset; int ret; - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - ret = __sys_sigprocmask(how, set, oset); - if (ret != 0) - ret = errno; - /* Get a fresh copy */ - __sys_sigprocmask(SIG_SETMASK, NULL, &curthread->sigmask); - return (ret); - } - - if (set) - newset = *set; - - THR_SCHED_LOCK(curthread, curthread); - - ret = 0; - if (oset != NULL) - /* Return the current mask: */ - oldset = curthread->sigmask; - - /* Check if a new signal set was provided by the caller: */ - if (set != NULL) { - /* Process according to what to do: */ - switch (how) { - /* Block signals: */ - case SIG_BLOCK: - /* Add signals to the existing mask: */ - SIGSETOR(curthread->sigmask, newset); - break; - - /* Unblock signals: */ - case SIG_UNBLOCK: - /* Clear signals from the existing mask: */ - SIGSETNAND(curthread->sigmask, newset); - break; - - /* Set the signal process mask: */ - case SIG_SETMASK: - /* Set the new mask: */ - curthread->sigmask = newset; - break; - - /* Trap invalid actions: */ - default: - /* Return an invalid argument: */ - ret = EINVAL; - break; - } - SIG_CANTMASK(curthread->sigmask); - THR_SCHED_UNLOCK(curthread, curthread); - - /* - * Run down any pending signals: - */ - if (ret == 0) - _thr_sig_check_pending(curthread); - } else - THR_SCHED_UNLOCK(curthread, curthread); - - if (ret == 0 && oset != NULL) - *oset = oldset; + ret = __sys_sigprocmask(how, set, oset); + if (ret != 0) + ret = errno; + /* Get a fresh copy */ + __sys_sigprocmask(SIG_SETMASK, NULL, &curthread->sigmask); return (ret); } ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigpending.c#2 (text+ko) ==== @@ -44,30 +44,5 @@ int _sigpending(sigset_t *set) { - struct pthread *curthread = _get_curthread(); - kse_critical_t crit; - sigset_t sigset; - int ret = 0; - - /* Check for a null signal set pointer: */ - if (set == NULL) { - /* Return an invalid argument: */ - ret = EINVAL; - } - else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sigpending(set)); - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, curthread->kseg); - sigset = curthread->sigpend; - KSE_SCHED_UNLOCK(curthread->kse, curthread->kseg); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); - SIGSETOR(sigset, _thr_proc_sigpending); - KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); - _kse_critical_leave(crit); - *set = sigset; - } - /* Return the completion status: */ - return (ret); + return (__sys_sigpending(set)); } ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigsuspend.c#2 (text+ko) ==== @@ -41,59 +41,13 @@ __weak_reference(__sigsuspend, sigsuspend); int -_sigsuspend(const sigset_t *set) -{ - struct pthread *curthread = _get_curthread(); - sigset_t oldmask, newmask, tempset; - int ret = -1; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sigsuspend(set)); - - /* Check if a new signal set was provided by the caller: */ - if (set != NULL) { - newmask = *set; - SIG_CANTMASK(newmask); - THR_LOCK_SWITCH(curthread); - - /* Save current sigmask: */ - oldmask = curthread->sigmask; - curthread->oldsigmask = &oldmask; - - /* Change the caller's mask: */ - curthread->sigmask = newmask; - tempset = curthread->sigpend; - SIGSETNAND(tempset, newmask); - if (SIGISEMPTY(tempset)) { - THR_SET_STATE(curthread, PS_SIGSUSPEND); - /* Wait for a signal: */ - _thr_sched_switch_unlocked(curthread); - } else { - THR_UNLOCK_SWITCH(curthread); - /* check pending signal I can handle: */ - _thr_sig_check_pending(curthread); - } - THR_ASSERT(curthread->oldsigmask == NULL, - "oldsigmask is not cleared"); - /* Always return an interrupted error: */ - errno = EINTR; - } else { - /* Return an invalid argument error: */ - errno = EINVAL; - } - - /* Return the completion status: */ - return (ret); -} - -int __sigsuspend(const sigset_t * set) { struct pthread *curthread = _get_curthread(); int ret; _thr_cancel_enter(curthread); - ret = _sigsuspend(set); + ret = __sys_sigsuspend(set); _thr_cancel_leave(curthread, 1); return (ret); ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sigwait.c#2 (text+ko) ==== @@ -43,93 +43,6 @@ __weak_reference(__sigtimedwait, sigtimedwait); __weak_reference(__sigwaitinfo, sigwaitinfo); -static int -lib_sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - int i; - struct sigwait_data waitdata; - sigset_t waitset; - kse_critical_t crit; - siginfo_t siginfo; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - if (info == NULL) - info = &siginfo; - return (__sys_sigtimedwait((sigset_t *)set, info, - (struct timespec *)timeout)); - } - - /* - * Initialize the set of signals that will be waited on: - */ - waitset = *set; - - /* These signals can't be waited on. */ - SIGDELSET(waitset, SIGKILL); - SIGDELSET(waitset, SIGSTOP); - - /* - * POSIX says that the _application_ must explicitly install - * a dummy handler for signals that are SIG_IGN in order - * to sigwait on them. Note that SIG_IGN signals are left in - * the mask because a subsequent sigaction could enable an - * ignored signal. - */ - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, curthread->kseg); - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(waitset, i) && - SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - siginfo = curthread->siginfo[i - 1]; - KSE_SCHED_UNLOCK(curthread->kse, - curthread->kseg); - _kse_critical_leave(crit); - ret = i; - goto OUT; - } - } - curthread->timeout = 0; - curthread->interrupted = 0; - _thr_set_timeout(timeout); - /* Wait for a signal: */ - siginfo.si_signo = 0; - waitdata.waitset = &waitset; - waitdata.siginfo = &siginfo; - curthread->data.sigwait = &waitdata; - THR_SET_STATE(curthread, PS_SIGWAIT); - _thr_sched_switch_unlocked(curthread); - /* - * Return the signal number to the caller: - */ - if (siginfo.si_signo > 0) { - ret = siginfo.si_signo; - } else { - if (curthread->interrupted) - errno = EINTR; - else if (curthread->timeout) - errno = EAGAIN; - ret = -1; - } - curthread->timeout = 0; - curthread->interrupted = 0; - /* - * Probably unnecessary, but since it's in a union struct - * we don't know how it could be used in the future. - */ - curthread->data.sigwait = NULL; - -OUT: - if (ret > 0 && info != NULL) - *info = siginfo; - - return (ret); -} - int __sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec * timeout) @@ -138,15 +51,16 @@ int ret; _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, info, timeout); + ret = __sys_sigtimedwait(set, info, timeout); _thr_cancel_leave(curthread, 1); return (ret); } -int _sigtimedwait(const sigset_t *set, siginfo_t *info, +int +_sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec * timeout) { - return lib_sigtimedwait(set, info, timeout); + return (__sys_sigtimedwait(set, info, timeout)); } int @@ -156,7 +70,7 @@ int ret; _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, info, NULL); + ret = __sys_sigwaitinfo(set, info); _thr_cancel_leave(curthread, 1); return (ret); } @@ -164,7 +78,7 @@ int _sigwaitinfo(const sigset_t *set, siginfo_t *info) { - return lib_sigtimedwait(set, info, NULL); + return (__sys_sigwaitinfo(set, info)); } int @@ -174,13 +88,7 @@ int ret; _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, NULL, NULL); - if (ret > 0) { - *sig = ret; - ret = 0; - } else { - ret = errno; - } + ret = __sys_sigwait(set, sig); _thr_cancel_leave(curthread, 1); return (ret); } @@ -188,15 +96,5 @@ int _sigwait(const sigset_t *set, int *sig) { - int ret; - - ret = lib_sigtimedwait(set, NULL, NULL); - if (ret > 0) { - *sig = ret; - ret = 0; - } else { - ret = errno; - } - return (ret); + return __sys_sigwait(set, sig); } -
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411200440.iAK4e3xD006302>