Deleted Added
sdiff udiff text old ( 114187 ) new ( 114254 )
full compact
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 114254 2003-04-29 21:03:33Z deischen $
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
44int
45_sigwait(const sigset_t *set, int *sig)
46{
47 struct pthread *curthread = _get_curthread();
48 int ret = 0;
49 int i;
50 sigset_t tempset, waitset;
51 struct sigaction act;
52 kse_critical_t crit;
53
54 _thr_enter_cancellation_point(curthread);
55
56 /*
57 * Specify the thread kernel signal handler.
58 */
59 act.sa_handler = (void (*) ()) _thr_sig_handler;
60 act.sa_flags = SA_RESTART | SA_SIGINFO;
61 /* Ensure the signal handler cannot be interrupted by other signals: */

--- 5 unchanged lines hidden (view full) ---

67 waitset = *set;
68
69 /* These signals can't be waited on. */
70 sigdelset(&waitset, SIGKILL);
71 sigdelset(&waitset, SIGSTOP);
72
73 /*
74 * Check to see if a pending signal is in the wait mask.
75 * This has to be atomic.
76 */
77 tempset = curthread->sigpend;
78 crit = _kse_critical_enter();
79 KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock);
80 SIGSETOR(tempset, _thr_proc_sigpending);
81 SIGSETAND(tempset, waitset);
82 if (SIGNOTEMPTY(tempset)) {
83 /* Enter a loop to find a pending signal: */
84 for (i = 1; i < NSIG; i++) {
85 if (sigismember (&tempset, i))
86 break;
87 }
88
89 /* Clear the pending signal: */
90 if (sigismember(&curthread->sigpend, i))
91 sigdelset(&curthread->sigpend, i);
92 else
93 sigdelset(&_thr_proc_sigpending, i);
94
95 KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock);
96 _kse_critical_leave(crit);
97 _thr_leave_cancellation_point(curthread);
98 /* Return the signal number to the caller: */
99 *sig = i;
100 return (0);
101 }
102
103 /*
104 * Enter a loop to find the signals that are SIG_DFL. For
105 * these signals we must install a dummy signal handler in
106 * order for the kernel to pass them in to us. POSIX says
107 * that the _application_ must explicitly install a dummy
108 * handler for signals that are SIG_IGN in order to sigwait
109 * on them. Note that SIG_IGN signals are left in the
110 * mask because a subsequent sigaction could enable an
111 * ignored signal.

--- 6 unchanged lines hidden (view full) ---

118 sigaddset(&tempset, i);
119 if (_thread_dfl_count[i] == 1) {
120 if (__sys_sigaction(i, &act, NULL) != 0)
121 ret = -1;
122 }
123 }
124 }
125 /* Done accessing _thread_dfl_count for now. */
126 KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock);
127 _kse_critical_leave(crit);
128 if (ret == 0) {
129 /*
130 * Save the wait signal mask. The wait signal
131 * mask is independent of the threads signal mask
132 * and requires separate storage.
133 */
134 curthread->data.sigwait = &waitset;
135

--- 10 unchanged lines hidden (view full) ---

146 * we don't know how it could be used in the future.
147 */
148 curthread->data.sigwait = NULL;
149 }
150
151 /*
152 * Relock the array of SIG_DFL wait counts.
153 */
154 crit = _kse_critical_enter();
155 KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock);
156
157 /* Restore the sigactions: */
158 act.sa_handler = SIG_DFL;
159 for (i = 1; i < NSIG; i++) {
160 if (sigismember(&tempset, i)) {
161 _thread_dfl_count[i]--;
162 if ((_thread_sigact[i - 1].sa_handler == SIG_DFL) &&
163 (_thread_dfl_count[i] == 0)) {
164 if (__sys_sigaction(i, &act, NULL) != 0)
165 ret = -1;
166 }
167 }
168 }
169 /* Done accessing _thread_dfl_count. */
170 KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock);
171 _kse_critical_leave(crit);
172 _thr_leave_cancellation_point(curthread);
173
174 /* Return the completion status: */
175 return (ret);
176}