Mercurial > hg > truffle
annotate src/os/solaris/vm/jsig.c @ 11918:234aea2460bb
removed the IterableNodeType marker interface from PhiNode (GRAAL-471)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Sun, 06 Oct 2013 23:45:02 +0200 |
parents | f95d63e2154a |
children |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 /* CopyrightVersion 1.2 */ | |
26 | |
27 /* This is a special library that should be loaded before libc & | |
28 * libthread to interpose the signal handler installation functions: | |
29 * sigaction(), signal(), sigset(). | |
30 * Used for signal-chaining. See RFE 4381843. | |
31 */ | |
32 | |
33 #include <stdlib.h> | |
34 #include <stdio.h> | |
35 #include <string.h> | |
36 #include <signal.h> | |
37 #include <dlfcn.h> | |
38 #include <thread.h> | |
39 #include <synch.h> | |
40 #include "jvm_solaris.h" | |
41 | |
42 #define bool int | |
43 #define true 1 | |
44 #define false 0 | |
45 | |
46 static struct sigaction *sact = (struct sigaction *)NULL; /* saved signal handlers */ | |
47 static sigset_t jvmsigs; | |
48 | |
49 /* used to synchronize the installation of signal handlers */ | |
50 static mutex_t mutex = DEFAULTMUTEX; | |
51 static cond_t cond = DEFAULTCV; | |
52 static thread_t tid = 0; | |
53 | |
54 typedef void (*sa_handler_t)(int); | |
55 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); | |
56 typedef sa_handler_t (*signal_t)(int, sa_handler_t); | |
57 typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *); | |
58 | |
59 static signal_t os_signal = 0; /* os's version of signal()/sigset() */ | |
60 static sigaction_t os_sigaction = 0; /* os's version of sigaction() */ | |
61 | |
62 static bool jvm_signal_installing = false; | |
63 static bool jvm_signal_installed = false; | |
64 | |
65 | |
66 /* assume called within signal_lock */ | |
67 static void allocate_sact() { | |
68 size_t maxsignum; | |
69 maxsignum = SIGRTMAX; | |
70 if (sact == NULL) { | |
71 sact = (struct sigaction *)malloc((maxsignum+1) * (size_t)sizeof(struct sigaction)); | |
72 memset(sact, 0, (maxsignum+1) * (size_t)sizeof(struct sigaction)); | |
73 } | |
74 | |
75 if (sact == NULL) { | |
76 printf("%s\n", "libjsig.so unable to allocate memory"); | |
77 exit(0); | |
78 } | |
79 | |
80 sigemptyset(&jvmsigs); | |
81 } | |
82 | |
83 static void signal_lock() { | |
84 mutex_lock(&mutex); | |
85 /* When the jvm is installing its set of signal handlers, threads | |
86 * other than the jvm thread should wait */ | |
87 if (jvm_signal_installing) { | |
88 if (tid != thr_self()) { | |
89 cond_wait(&cond, &mutex); | |
90 } | |
91 } | |
92 } | |
93 | |
94 static void signal_unlock() { | |
95 mutex_unlock(&mutex); | |
96 } | |
97 | |
98 static sa_handler_t call_os_signal(int sig, sa_handler_t disp, | |
99 bool is_sigset) { | |
100 if (os_signal == NULL) { | |
101 if (!is_sigset) { | |
102 os_signal = (signal_t)dlsym(RTLD_NEXT, "signal"); | |
103 } else { | |
104 os_signal = (signal_t)dlsym(RTLD_NEXT, "sigset"); | |
105 } | |
106 if (os_signal == NULL) { | |
107 printf("%s\n", dlerror()); | |
108 exit(0); | |
109 } | |
110 } | |
111 return (*os_signal)(sig, disp); | |
112 } | |
113 | |
114 static void save_signal_handler(int sig, sa_handler_t disp, bool is_sigset) { | |
115 sigset_t set; | |
116 if (sact == NULL) { | |
117 allocate_sact(); | |
118 } | |
119 sact[sig].sa_handler = disp; | |
120 sigemptyset(&set); | |
121 sact[sig].sa_mask = set; | |
122 if (!is_sigset) { | |
123 sact[sig].sa_flags = SA_NODEFER; | |
124 if (sig != SIGILL && sig != SIGTRAP && sig != SIGPWR) { | |
125 sact[sig].sa_flags |= SA_RESETHAND; | |
126 } | |
127 } else { | |
128 sact[sig].sa_flags = 0; | |
129 } | |
130 } | |
131 | |
132 static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) { | |
133 sa_handler_t oldhandler; | |
134 bool sigblocked; | |
135 | |
136 signal_lock(); | |
137 if (sact == NULL) { | |
138 allocate_sact(); | |
139 } | |
140 | |
141 if (jvm_signal_installed && sigismember(&jvmsigs, sig)) { | |
142 /* jvm has installed its signal handler for this signal. */ | |
143 /* Save the handler. Don't really install it. */ | |
144 if (is_sigset) { | |
145 /* We won't honor the SIG_HOLD request to change the signal mask */ | |
146 sigblocked = sigismember(&(sact[sig].sa_mask), sig); | |
147 } | |
148 oldhandler = sact[sig].sa_handler; | |
149 save_signal_handler(sig, disp, is_sigset); | |
150 | |
151 if (is_sigset && sigblocked) { | |
152 oldhandler = SIG_HOLD; | |
153 } | |
154 | |
155 signal_unlock(); | |
156 return oldhandler; | |
157 } else if (jvm_signal_installing) { | |
158 /* jvm is installing its signal handlers. Install the new | |
159 * handlers and save the old ones. jvm uses sigaction(). | |
160 * Leave the piece here just in case. */ | |
161 oldhandler = call_os_signal(sig, disp, is_sigset); | |
162 save_signal_handler(sig, oldhandler, is_sigset); | |
163 | |
164 /* Record the signals used by jvm */ | |
165 sigaddset(&jvmsigs, sig); | |
166 | |
167 signal_unlock(); | |
168 return oldhandler; | |
169 } else { | |
170 /* jvm has no relation with this signal (yet). Install the | |
171 * the handler. */ | |
172 oldhandler = call_os_signal(sig, disp, is_sigset); | |
173 | |
174 signal_unlock(); | |
175 return oldhandler; | |
176 } | |
177 } | |
178 | |
179 sa_handler_t signal(int sig, sa_handler_t disp) { | |
180 return set_signal(sig, disp, false); | |
181 } | |
182 | |
183 sa_handler_t sigset(int sig, sa_handler_t disp) { | |
184 return set_signal(sig, disp, true); | |
185 } | |
186 | |
187 static int call_os_sigaction(int sig, const struct sigaction *act, | |
188 struct sigaction *oact) { | |
189 if (os_sigaction == NULL) { | |
190 os_sigaction = (sigaction_t)dlsym(RTLD_NEXT, "sigaction"); | |
191 if (os_sigaction == NULL) { | |
192 printf("%s\n", dlerror()); | |
193 exit(0); | |
194 } | |
195 } | |
196 return (*os_sigaction)(sig, act, oact); | |
197 } | |
198 | |
199 int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { | |
200 int res; | |
201 struct sigaction oldAct; | |
202 | |
203 signal_lock(); | |
204 | |
205 if (sact == NULL ) { | |
206 allocate_sact(); | |
207 } | |
208 if (jvm_signal_installed && sigismember(&jvmsigs, sig)) { | |
209 /* jvm has installed its signal handler for this signal. */ | |
210 /* Save the handler. Don't really install it. */ | |
211 if (oact != NULL) { | |
212 *oact = sact[sig]; | |
213 } | |
214 if (act != NULL) { | |
215 sact[sig] = *act; | |
216 } | |
217 | |
218 signal_unlock(); | |
219 return 0; | |
220 } else if (jvm_signal_installing) { | |
221 /* jvm is installing its signal handlers. Install the new | |
222 * handlers and save the old ones. */ | |
223 res = call_os_sigaction(sig, act, &oldAct); | |
224 sact[sig] = oldAct; | |
225 if (oact != NULL) { | |
226 *oact = oldAct; | |
227 } | |
228 | |
229 /* Record the signals used by jvm */ | |
230 sigaddset(&jvmsigs, sig); | |
231 | |
232 signal_unlock(); | |
233 return res; | |
234 } else { | |
235 /* jvm has no relation with this signal (yet). Install the | |
236 * the handler. */ | |
237 res = call_os_sigaction(sig, act, oact); | |
238 | |
239 signal_unlock(); | |
240 return res; | |
241 } | |
242 } | |
243 | |
244 /* The four functions for the jvm to call into */ | |
245 void JVM_begin_signal_setting() { | |
246 signal_lock(); | |
247 jvm_signal_installing = true; | |
248 tid = thr_self(); | |
249 signal_unlock(); | |
250 } | |
251 | |
252 void JVM_end_signal_setting() { | |
253 signal_lock(); | |
254 jvm_signal_installed = true; | |
255 jvm_signal_installing = false; | |
256 cond_broadcast(&cond); | |
257 signal_unlock(); | |
258 } | |
259 | |
260 struct sigaction *JVM_get_signal_action(int sig) { | |
261 if (sact == NULL) { | |
262 allocate_sact(); | |
263 } | |
264 /* Does race condition make sense here? */ | |
265 if (sigismember(&jvmsigs, sig)) { | |
266 return &sact[sig]; | |
267 } | |
268 return NULL; | |
269 } | |
270 | |
271 int JVM_get_libjsig_version() { | |
272 return JSIG_VERSION_1_4_1; | |
273 } |