Mercurial > hg > truffle
annotate src/os/linux/vm/jsig.c @ 4582:b24386206122
Made all vm builds go into subdirectories, even product builds to simplify building the various types of VMs (server, client and graal).
Made HotSpot build jobs use the number of CPUs on the host machine.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 13 Feb 2012 23:13:37 +0100 |
parents | f95d63e2154a |
children | 732af649bc3a |
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 <signal.h> | |
34 #include <dlfcn.h> | |
35 #include <pthread.h> | |
36 #include <stdio.h> | |
37 #include <stdlib.h> | |
38 | |
39 #define bool int | |
40 #define true 1 | |
41 #define false 0 | |
42 | |
43 #define MAXSIGNUM 32 | |
44 #define MASK(sig) ((unsigned int)1 << sig) | |
45 | |
46 static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ | |
47 static unsigned int jvmsigs = 0; /* signals used by jvm */ | |
48 | |
49 /* used to synchronize the installation of signal handlers */ | |
50 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | |
51 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | |
52 static pthread_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 static void signal_lock() { | |
66 pthread_mutex_lock(&mutex); | |
67 /* When the jvm is installing its set of signal handlers, threads | |
68 * other than the jvm thread should wait */ | |
69 if (jvm_signal_installing) { | |
70 if (tid != pthread_self()) { | |
71 pthread_cond_wait(&cond, &mutex); | |
72 } | |
73 } | |
74 } | |
75 | |
76 static void signal_unlock() { | |
77 pthread_mutex_unlock(&mutex); | |
78 } | |
79 | |
80 static sa_handler_t call_os_signal(int sig, sa_handler_t disp, | |
81 bool is_sigset) { | |
82 if (os_signal == NULL) { | |
83 if (!is_sigset) { | |
84 os_signal = (signal_t)dlsym(RTLD_NEXT, "signal"); | |
85 } else { | |
86 os_signal = (signal_t)dlsym(RTLD_NEXT, "sigset"); | |
87 } | |
88 if (os_signal == NULL) { | |
89 printf("%s\n", dlerror()); | |
90 exit(0); | |
91 } | |
92 } | |
93 return (*os_signal)(sig, disp); | |
94 } | |
95 | |
96 static void save_signal_handler(int sig, sa_handler_t disp) { | |
97 sigset_t set; | |
98 sact[sig].sa_handler = disp; | |
99 sigemptyset(&set); | |
100 sact[sig].sa_mask = set; | |
101 sact[sig].sa_flags = 0; | |
102 } | |
103 | |
104 static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) { | |
105 sa_handler_t oldhandler; | |
106 bool sigused; | |
107 | |
108 signal_lock(); | |
109 | |
110 sigused = (MASK(sig) & jvmsigs) != 0; | |
111 if (jvm_signal_installed && sigused) { | |
112 /* jvm has installed its signal handler for this signal. */ | |
113 /* Save the handler. Don't really install it. */ | |
114 oldhandler = sact[sig].sa_handler; | |
115 save_signal_handler(sig, disp); | |
116 | |
117 signal_unlock(); | |
118 return oldhandler; | |
119 } else if (jvm_signal_installing) { | |
120 /* jvm is installing its signal handlers. Install the new | |
121 * handlers and save the old ones. jvm uses sigaction(). | |
122 * Leave the piece here just in case. */ | |
123 oldhandler = call_os_signal(sig, disp, is_sigset); | |
124 save_signal_handler(sig, oldhandler); | |
125 | |
126 /* Record the signals used by jvm */ | |
127 jvmsigs |= MASK(sig); | |
128 | |
129 signal_unlock(); | |
130 return oldhandler; | |
131 } else { | |
132 /* jvm has no relation with this signal (yet). Install the | |
133 * the handler. */ | |
134 oldhandler = call_os_signal(sig, disp, is_sigset); | |
135 | |
136 signal_unlock(); | |
137 return oldhandler; | |
138 } | |
139 } | |
140 | |
141 sa_handler_t signal(int sig, sa_handler_t disp) { | |
142 return set_signal(sig, disp, false); | |
143 } | |
144 | |
145 sa_handler_t sigset(int sig, sa_handler_t disp) { | |
146 return set_signal(sig, disp, true); | |
147 } | |
148 | |
149 static int call_os_sigaction(int sig, const struct sigaction *act, | |
150 struct sigaction *oact) { | |
151 if (os_sigaction == NULL) { | |
152 os_sigaction = (sigaction_t)dlsym(RTLD_NEXT, "sigaction"); | |
153 if (os_sigaction == NULL) { | |
154 printf("%s\n", dlerror()); | |
155 exit(0); | |
156 } | |
157 } | |
158 return (*os_sigaction)(sig, act, oact); | |
159 } | |
160 | |
161 int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { | |
162 int res; | |
163 bool sigused; | |
164 struct sigaction oldAct; | |
165 | |
166 signal_lock(); | |
167 | |
168 sigused = (MASK(sig) & jvmsigs) != 0; | |
169 if (jvm_signal_installed && sigused) { | |
170 /* jvm has installed its signal handler for this signal. */ | |
171 /* Save the handler. Don't really install it. */ | |
172 if (oact != NULL) { | |
173 *oact = sact[sig]; | |
174 } | |
175 if (act != NULL) { | |
176 sact[sig] = *act; | |
177 } | |
178 | |
179 signal_unlock(); | |
180 return 0; | |
181 } else if (jvm_signal_installing) { | |
182 /* jvm is installing its signal handlers. Install the new | |
183 * handlers and save the old ones. */ | |
184 res = call_os_sigaction(sig, act, &oldAct); | |
185 sact[sig] = oldAct; | |
186 if (oact != NULL) { | |
187 *oact = oldAct; | |
188 } | |
189 | |
190 /* Record the signals used by jvm */ | |
191 jvmsigs |= MASK(sig); | |
192 | |
193 signal_unlock(); | |
194 return res; | |
195 } else { | |
196 /* jvm has no relation with this signal (yet). Install the | |
197 * the handler. */ | |
198 res = call_os_sigaction(sig, act, oact); | |
199 | |
200 signal_unlock(); | |
201 return res; | |
202 } | |
203 } | |
204 | |
205 /* The three functions for the jvm to call into */ | |
206 void JVM_begin_signal_setting() { | |
207 signal_lock(); | |
208 jvm_signal_installing = true; | |
209 tid = pthread_self(); | |
210 signal_unlock(); | |
211 } | |
212 | |
213 void JVM_end_signal_setting() { | |
214 signal_lock(); | |
215 jvm_signal_installed = true; | |
216 jvm_signal_installing = false; | |
217 pthread_cond_broadcast(&cond); | |
218 signal_unlock(); | |
219 } | |
220 | |
221 struct sigaction *JVM_get_signal_action(int sig) { | |
222 /* Does race condition make sense here? */ | |
223 if ((MASK(sig) & jvmsigs) != 0) { | |
224 return &sact[sig]; | |
225 } | |
226 return NULL; | |
227 } |