thr_sigwait.c (117353) | thr_sigwait.c (117706) |
---|---|
1//depot/projects/kse/lib/libpthread/thread/thr_sigwait.c#1 - branch change 15154 (text+ko) 2/* 3 * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 16 unchanged lines hidden (view full) --- 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * | 1//depot/projects/kse/lib/libpthread/thread/thr_sigwait.c#1 - branch change 15154 (text+ko) 2/* 3 * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 16 unchanged lines hidden (view full) --- 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * |
33 * $FreeBSD: head/lib/libkse/thread/thr_sigwait.c 117353 2003-07-09 14:30:51Z davidxu $ | 33 * $FreeBSD: head/lib/libkse/thread/thr_sigwait.c 117706 2003-07-17 23:02:30Z davidxu $ |
34 */ 35#include <signal.h> 36#include <sys/param.h> 37#include <sys/signalvar.h> 38#include <errno.h> 39#include <pthread.h> 40#include "thr_private.h" 41 42__weak_reference(__sigwait, sigwait); 43__weak_reference(__sigtimedwait, sigtimedwait); 44__weak_reference(__sigwaitinfo, sigwaitinfo); 45 46static int 47lib_sigtimedwait(const sigset_t *set, siginfo_t *info, 48 const struct timespec * timeout) 49{ 50 struct pthread *curthread = _get_curthread(); 51 int ret = 0; 52 int i; | 34 */ 35#include <signal.h> 36#include <sys/param.h> 37#include <sys/signalvar.h> 38#include <errno.h> 39#include <pthread.h> 40#include "thr_private.h" 41 42__weak_reference(__sigwait, sigwait); 43__weak_reference(__sigtimedwait, sigtimedwait); 44__weak_reference(__sigwaitinfo, sigwaitinfo); 45 46static int 47lib_sigtimedwait(const sigset_t *set, siginfo_t *info, 48 const struct timespec * timeout) 49{ 50 struct pthread *curthread = _get_curthread(); 51 int ret = 0; 52 int i; |
53 sigset_t tempset, waitset; 54 struct sigaction act; | 53 sigset_t waitset; |
55 kse_critical_t crit; 56 siginfo_t siginfo; 57 | 54 kse_critical_t crit; 55 siginfo_t siginfo; 56 |
58 if (!_kse_isthreaded()) { | 57 if (!_kse_isthreaded() || 58 (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) { |
59 if (info == NULL) 60 info = &siginfo; | 59 if (info == NULL) 60 info = &siginfo; |
61 return __sys_sigtimedwait((sigset_t *)set, info, 62 (struct timespec *)timeout); | 61 return (__sys_sigtimedwait((sigset_t *)set, info, 62 (struct timespec *)timeout)); |
63 } 64 65 /* | 63 } 64 65 /* |
66 * Specify the thread kernel signal handler. 67 */ 68 act.sa_handler = (void (*) ()) _thr_sig_handler; 69 act.sa_flags = SA_RESTART | SA_SIGINFO; 70 /* Ensure the signal handler cannot be interrupted by other signals: */ 71 SIGFILLSET(act.sa_mask); 72 73 /* | |
74 * Initialize the set of signals that will be waited on: 75 */ 76 waitset = *set; 77 78 /* These signals can't be waited on. */ 79 SIGDELSET(waitset, SIGKILL); 80 SIGDELSET(waitset, SIGSTOP); 81 | 66 * Initialize the set of signals that will be waited on: 67 */ 68 waitset = *set; 69 70 /* These signals can't be waited on. */ 71 SIGDELSET(waitset, SIGKILL); 72 SIGDELSET(waitset, SIGSTOP); 73 |
82 crit = _kse_critical_enter(); 83 KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); 84 | |
85 /* | 74 /* |
86 * Enter a loop to find the signals that are SIG_DFL. For 87 * these signals we must install a dummy signal handler in 88 * order for the kernel to pass them in to us. POSIX says 89 * that the _application_ must explicitly install a dummy 90 * handler for signals that are SIG_IGN in order to sigwait 91 * on them. Note that SIG_IGN signals are left in the 92 * mask because a subsequent sigaction could enable an | 75 * POSIX says that the _application_ must explicitly install 76 * a dummy handler for signals that are SIG_IGN in order 77 * to sigwait on them. Note that SIG_IGN signals are left in 78 * the mask because a subsequent sigaction could enable an |
93 * ignored signal. 94 */ | 79 * ignored signal. 80 */ |
95 SIGEMPTYSET(tempset); 96 for (i = 1; i <= _SIG_MAXSIG; i++) { | 81 82 crit = _kse_critical_enter(); 83 KSE_SCHED_LOCK(curthread->kse, curthread->kseg); 84 for (i = 1; i <= _SIG_MAXSIG; ++i) { |
97 if (SIGISMEMBER(waitset, i) && | 85 if (SIGISMEMBER(waitset, i) && |
98 (_thread_sigact[i - 1].sa_handler == SIG_DFL)) { 99 _thread_dfl_count[i - 1]++; 100 SIGADDSET(tempset, i); 101 if (_thread_dfl_count[i - 1] == 1) { 102 if (__sys_sigaction(i, &act, NULL) != 0) 103 /* ret = -1 */; 104 } | 86 SIGISMEMBER(curthread->sigpend, i)) { 87 SIGDELSET(curthread->sigpend, i); 88 siginfo = curthread->siginfo[i - 1]; 89 KSE_SCHED_UNLOCK(curthread->kse, 90 curthread->kseg); 91 _kse_critical_leave(crit); 92 ret = i; 93 goto OUT; |
105 } 106 } | 94 } 95 } |
107 108 if (ret == 0) { 109 /* Done accessing _thread_dfl_count for now. */ 110 KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); 111 KSE_SCHED_LOCK(curthread->kse, curthread->kseg); 112 for (i = 1; i <= _SIG_MAXSIG; ++i) { 113 if (SIGISMEMBER(waitset, i) && 114 SIGISMEMBER(curthread->sigpend, i)) { 115 SIGDELSET(curthread->sigpend, i); 116 siginfo = curthread->siginfo[i - 1]; 117 KSE_SCHED_UNLOCK(curthread->kse, 118 curthread->kseg); 119 KSE_LOCK_ACQUIRE(curthread->kse, 120 &_thread_signal_lock); 121 ret = i; 122 goto OUT; 123 } 124 } 125 curthread->timeout = 0; 126 curthread->interrupted = 0; 127 _thr_set_timeout(timeout); 128 /* Wait for a signal: */ 129 curthread->oldsigmask = curthread->sigmask; 130 siginfo.si_signo = 0; 131 curthread->data.sigwaitinfo = &siginfo; 132 SIGFILLSET(curthread->sigmask); 133 SIGSETNAND(curthread->sigmask, waitset); 134 THR_SET_STATE(curthread, PS_SIGWAIT); 135 _thr_sched_switch_unlocked(curthread); 136 /* 137 * Return the signal number to the caller: 138 */ 139 if (siginfo.si_signo > 0) { 140 ret = siginfo.si_signo; 141 } else { 142 if (curthread->interrupted) 143 errno = EINTR; 144 else if (curthread->timeout) 145 errno = EAGAIN; 146 ret = -1; 147 } 148 curthread->timeout = 0; 149 curthread->interrupted = 0; 150 /* 151 * Probably unnecessary, but since it's in a union struct 152 * we don't know how it could be used in the future. 153 */ 154 crit = _kse_critical_enter(); 155 curthread->data.sigwaitinfo = NULL; 156 /* 157 * Relock the array of SIG_DFL wait counts. 158 */ 159 KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); | 96 curthread->timeout = 0; 97 curthread->interrupted = 0; 98 _thr_set_timeout(timeout); 99 /* Wait for a signal: */ 100 curthread->oldsigmask = curthread->sigmask; 101 siginfo.si_signo = 0; 102 curthread->data.sigwaitinfo = &siginfo; 103 SIGFILLSET(curthread->sigmask); 104 SIGSETNAND(curthread->sigmask, waitset); 105 THR_SET_STATE(curthread, PS_SIGWAIT); 106 _thr_sched_switch_unlocked(curthread); 107 /* 108 * Return the signal number to the caller: 109 */ 110 if (siginfo.si_signo > 0) { 111 ret = siginfo.si_signo; 112 } else { 113 if (curthread->interrupted) 114 errno = EINTR; 115 else if (curthread->timeout) 116 errno = EAGAIN; 117 ret = -1; |
160 } | 118 } |
119 curthread->timeout = 0; 120 curthread->interrupted = 0; 121 /* 122 * Probably unnecessary, but since it's in a union struct 123 * we don't know how it could be used in the future. 124 */ 125 curthread->data.sigwaitinfo = NULL; |
|
161 162OUT: | 126 127OUT: |
163 /* Restore the sigactions: */ 164 act.sa_handler = SIG_DFL; 165 for (i = 1; i <= _SIG_MAXSIG; i++) { 166 if (SIGISMEMBER(tempset, i)) { 167 _thread_dfl_count[i - 1]--; 168 if ((_thread_sigact[i - 1].sa_handler == SIG_DFL) && 169 (_thread_dfl_count[i - 1] == 0)) { 170 if (__sys_sigaction(i, &act, NULL) != 0) 171 /* ret = -1 */ ; 172 } 173 } 174 } 175 /* Done accessing _thread_dfl_count. */ 176 KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); 177 _kse_critical_leave(crit); 178 | |
179 if (ret > 0 && info != NULL) 180 *info = siginfo; 181 182 return (ret); 183} 184 185int 186__sigtimedwait(const sigset_t *set, siginfo_t *info, --- 68 unchanged lines hidden --- | 128 if (ret > 0 && info != NULL) 129 *info = siginfo; 130 131 return (ret); 132} 133 134int 135__sigtimedwait(const sigset_t *set, siginfo_t *info, --- 68 unchanged lines hidden --- |