71
71
import com .oracle .truffle .api .library .CachedLibrary ;
72
72
import com .oracle .truffle .api .object .HiddenKey ;
73
73
74
+ import sun .misc .SignalHandler ;
75
+
74
76
@ CoreFunctions (defineModule = "_signal" )
75
77
public class SignalModuleBuiltins extends PythonBuiltins {
76
- private static ConcurrentHashMap <Integer , Object > signalHandlers = new ConcurrentHashMap <>();
78
+ private static final ConcurrentHashMap <Integer , Object > signalHandlers = new ConcurrentHashMap <>();
79
+ private static final ConcurrentHashMap <Integer , SignalHandler > defaultSignalHandlers = new ConcurrentHashMap <>();
77
80
78
81
private static final HiddenKey signalQueueKey = new HiddenKey ("signalQueue" );
79
82
private final ConcurrentLinkedDeque <SignalTriggerAction > signalQueue = new ConcurrentLinkedDeque <>();
@@ -172,22 +175,34 @@ int alarmOvf(PInt seconds) {
172
175
}
173
176
}
174
177
178
+ @ TruffleBoundary
179
+ private static Object handlerToPython (SignalHandler handler , int signum ) {
180
+ if (handler == sun .misc .SignalHandler .SIG_DFL ) {
181
+ return Signals .SIG_DFL ;
182
+ } else if (handler == sun .misc .SignalHandler .SIG_IGN ) {
183
+ return Signals .SIG_IGN ;
184
+ } else if (handler instanceof Signals .PythonSignalHandler ) {
185
+ return signalHandlers .getOrDefault (signum , PNone .NONE );
186
+ } else {
187
+ // Save default JVM handlers to be restored later
188
+ defaultSignalHandlers .put (signum , handler );
189
+ return Signals .SIG_DFL ;
190
+ }
191
+ }
192
+
175
193
@ Builtin (name = "getsignal" , minNumOfPositionalArgs = 1 )
176
194
@ GenerateNodeFactory
177
195
abstract static class GetSignalNode extends PythonUnaryBuiltinNode {
178
196
@ Specialization
179
197
@ TruffleBoundary
180
198
Object getsignal (int signum ) {
181
- int currentSignalHandler = Signals .getCurrentSignalHandler (signum );
182
- if (currentSignalHandler == Signals .SIG_UNKNOWN ) {
183
- if (signalHandlers .containsKey (signum )) {
184
- return signalHandlers .get (signum );
185
- } else {
186
- return PNone .NONE ;
187
- }
188
- } else {
189
- return currentSignalHandler ;
190
- }
199
+ return handlerToPython (Signals .getCurrentSignalHandler (signum ), signum );
200
+ }
201
+
202
+ @ Specialization (limit = "3" )
203
+ Object getsignal (Object signum ,
204
+ @ CachedLibrary ("signum" ) PythonObjectLibrary lib ) {
205
+ return getsignal (lib .asSize (signum ));
191
206
}
192
207
}
193
208
@@ -218,21 +233,19 @@ Object signalId(@SuppressWarnings("unused") PythonModule self, Object signal, Ob
218
233
219
234
@ TruffleBoundary
220
235
private Object signal (int signum , int id ) {
221
- Object retval ;
236
+ SignalHandler oldHandler ;
222
237
try {
223
- retval = Signals .setSignalHandler (signum , id );
224
- } catch (IllegalArgumentException e ) {
225
- throw raise (PythonErrorType .TypeError , ErrorMessages .SIGNAL_MUST_BE_SIGIGN_SIGDFL_OR_CALLABLE_OBJ );
226
- }
227
- if ((int ) retval == Signals .SIG_UNKNOWN ) {
228
- if (signalHandlers .containsKey (signum )) {
229
- retval = signalHandlers .get (signum );
238
+ if (id == Signals .SIG_DFL && defaultSignalHandlers .containsKey (signum )) {
239
+ oldHandler = Signals .setSignalHandler (signum , defaultSignalHandlers .get (signum ));
230
240
} else {
231
- retval = PNone . NONE ;
241
+ oldHandler = Signals . setSignalHandler ( signum , id ) ;
232
242
}
243
+ } catch (IllegalArgumentException e ) {
244
+ throw raise (PythonErrorType .TypeError , ErrorMessages .SIGNAL_MUST_BE_SIGIGN_SIGDFL_OR_CALLABLE_OBJ );
233
245
}
234
- signalHandlers .put (signum , id );
235
- return retval ;
246
+ Object result = handlerToPython (oldHandler , signum );
247
+ signalHandlers .remove (signum );
248
+ return result ;
236
249
}
237
250
238
251
@ Specialization (guards = "handlerLib.isCallable(handler)" , limit = "1" )
@@ -248,25 +261,19 @@ Object signalHandler(PythonModule self, Object signal, Object handler,
248
261
private Object signal (PythonModule self , int signum , Object handler , ReadAttributeFromObjectNode readQueueNode , ReadAttributeFromObjectNode readSemaNode ) {
249
262
ConcurrentLinkedDeque <SignalTriggerAction > queue = getQueue (self , readQueueNode );
250
263
Semaphore semaphore = getSemaphore (self , readSemaNode );
251
- Object retval ;
264
+ SignalHandler oldHandler ;
252
265
SignalTriggerAction signalTrigger = new SignalTriggerAction (handler , signum );
253
266
try {
254
- retval = Signals .setSignalHandler (signum , () -> {
267
+ oldHandler = Signals .setSignalHandler (signum , () -> {
255
268
queue .add (signalTrigger );
256
269
semaphore .release ();
257
270
});
258
271
} catch (IllegalArgumentException e ) {
259
272
throw raise (PythonErrorType .ValueError , e );
260
273
}
261
- if ((int ) retval == Signals .SIG_UNKNOWN ) {
262
- if (signalHandlers .containsKey (signum )) {
263
- retval = signalHandlers .get (signum );
264
- } else {
265
- retval = PNone .NONE ;
266
- }
267
- }
274
+ Object result = handlerToPython (oldHandler , signum );
268
275
signalHandlers .put (signum , handler );
269
- return retval ;
276
+ return result ;
270
277
}
271
278
272
279
@ SuppressWarnings ("unchecked" )
@@ -299,7 +306,6 @@ private static Semaphore getSemaphore(PythonModule self, ReadAttributeFromObject
299
306
final class Signals {
300
307
static final int SIG_DFL = 0 ;
301
308
static final int SIG_IGN = 1 ;
302
- static final int SIG_UNKNOWN = -1 ;
303
309
private static final int SIGMAX = 31 ;
304
310
static final String [] signalNames = new String [SIGMAX + 1 ];
305
311
@@ -342,7 +348,7 @@ synchronized static void scheduleAlarm(long seconds) {
342
348
new Thread (new Alarm (seconds )).start ();
343
349
}
344
350
345
- private static class PythonSignalHandler implements sun .misc .SignalHandler {
351
+ static class PythonSignalHandler implements sun .misc .SignalHandler {
346
352
private final Runnable handler ;
347
353
348
354
public PythonSignalHandler (Runnable handler ) {
@@ -360,13 +366,17 @@ static String signalNumberToName(int signum) {
360
366
}
361
367
362
368
@ TruffleBoundary
363
- synchronized static int setSignalHandler (int signum , Runnable handler ) throws IllegalArgumentException {
364
- sun .misc .SignalHandler oldH = sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), new PythonSignalHandler (handler ));
365
- return handlerToInt (oldH );
369
+ synchronized static SignalHandler setSignalHandler (int signum , Runnable handler ) throws IllegalArgumentException {
370
+ return setSignalHandler (signum , new PythonSignalHandler (handler ));
366
371
}
367
372
368
373
@ TruffleBoundary
369
- synchronized static int setSignalHandler (int signum , int handler ) throws IllegalArgumentException {
374
+ synchronized static SignalHandler setSignalHandler (int signum , SignalHandler handler ) throws IllegalArgumentException {
375
+ return sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), handler );
376
+ }
377
+
378
+ @ TruffleBoundary
379
+ synchronized static SignalHandler setSignalHandler (int signum , int handler ) throws IllegalArgumentException {
370
380
sun .misc .SignalHandler h ;
371
381
if (handler == SIG_DFL ) {
372
382
h = sun .misc .SignalHandler .SIG_DFL ;
@@ -375,34 +385,24 @@ synchronized static int setSignalHandler(int signum, int handler) throws Illegal
375
385
} else {
376
386
throw new IllegalArgumentException ();
377
387
}
378
- return handlerToInt ( sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), h ) );
388
+ return sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), h );
379
389
}
380
390
381
391
@ TruffleBoundary
382
- synchronized static int getCurrentSignalHandler (int signum ) {
392
+ synchronized static SignalHandler getCurrentSignalHandler (int signum ) {
383
393
// To check what the current signal handler, we install default to get the current one
384
394
// and immediately replace it again.
385
395
sun .misc .SignalHandler oldH ;
386
396
try {
387
397
oldH = sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), sun .misc .SignalHandler .SIG_DFL );
388
398
} catch (IllegalArgumentException e ) {
389
- return SIG_DFL ;
399
+ return sun . misc . SignalHandler . SIG_DFL ;
390
400
}
391
401
try {
392
402
sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), oldH );
393
403
} catch (IllegalArgumentException e ) {
394
- return SIG_DFL ;
395
- }
396
- return handlerToInt (oldH );
397
- }
398
-
399
- private static int handlerToInt (sun .misc .SignalHandler oldH ) {
400
- if (oldH == sun .misc .SignalHandler .SIG_DFL ) {
401
- return SIG_DFL ;
402
- } else if (oldH == sun .misc .SignalHandler .SIG_IGN ) {
403
- return SIG_IGN ;
404
- } else {
405
- return SIG_UNKNOWN ;
404
+ return sun .misc .SignalHandler .SIG_DFL ;
406
405
}
406
+ return oldH ;
407
407
}
408
408
}
0 commit comments