52
52
import com .oracle .graal .python .builtins .objects .ints .PInt ;
53
53
import com .oracle .graal .python .builtins .objects .module .PythonModule ;
54
54
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
55
+ import com .oracle .graal .python .builtins .objects .signal .PJavaSignalHandler ;
55
56
import com .oracle .graal .python .nodes .ErrorMessages ;
56
57
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
57
58
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
62
63
import com .oracle .graal .python .runtime .AsyncHandler ;
63
64
import com .oracle .graal .python .runtime .PythonCore ;
64
65
import com .oracle .graal .python .runtime .exception .PythonErrorType ;
66
+ import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
65
67
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
66
68
import com .oracle .truffle .api .dsl .Cached ;
67
69
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
71
73
import com .oracle .truffle .api .library .CachedLibrary ;
72
74
import com .oracle .truffle .api .object .HiddenKey ;
73
75
76
+ import sun .misc .SignalHandler ;
77
+
74
78
@ CoreFunctions (defineModule = "_signal" )
75
79
public class SignalModuleBuiltins extends PythonBuiltins {
76
80
private static ConcurrentHashMap <Integer , Object > signalHandlers = new ConcurrentHashMap <>();
@@ -172,22 +176,35 @@ int alarmOvf(PInt seconds) {
172
176
}
173
177
}
174
178
179
+ private static Object handlerToPython (PythonObjectFactory factory , 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
+ if (signalHandlers .containsKey (signum )) {
186
+ return signalHandlers .get (signum );
187
+ } else {
188
+ return PNone .NONE ;
189
+ }
190
+ } else {
191
+ return factory .createJavaSignalHandler (handler );
192
+ }
193
+ }
194
+
175
195
@ Builtin (name = "getsignal" , minNumOfPositionalArgs = 1 )
176
196
@ GenerateNodeFactory
177
197
abstract static class GetSignalNode extends PythonUnaryBuiltinNode {
178
198
@ Specialization
179
199
@ TruffleBoundary
180
200
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
- }
201
+ return handlerToPython (factory (), Signals .getCurrentSignalHandler (signum ), signum );
202
+ }
203
+
204
+ @ Specialization (limit = "3" )
205
+ Object getsignal (Object signum ,
206
+ @ CachedLibrary ("signum" ) PythonObjectLibrary lib ) {
207
+ return getsignal (lib .asSize (signum ));
191
208
}
192
209
}
193
210
@@ -205,7 +222,7 @@ Object defaultIntHandler(@SuppressWarnings("unused") Object[] args) {
205
222
@ GenerateNodeFactory
206
223
abstract static class SignalNode extends PythonTernaryBuiltinNode {
207
224
208
- @ Specialization (guards = "!idNumLib.isCallable(idNum)" , limit = "1" )
225
+ @ Specialization (guards = { "!idNumLib.isCallable(idNum)" , "!isJavaHandler(idNum)" } , limit = "1" )
209
226
Object signalId (@ SuppressWarnings ("unused" ) PythonModule self , Object signal , Object idNum ,
210
227
@ SuppressWarnings ("unused" ) @ CachedLibrary ("idNum" ) PythonObjectLibrary idNumLib ,
211
228
@ CachedLibrary ("signal" ) PythonObjectLibrary signalLib ) {
@@ -218,21 +235,28 @@ Object signalId(@SuppressWarnings("unused") PythonModule self, Object signal, Ob
218
235
219
236
@ TruffleBoundary
220
237
private Object signal (int signum , int id ) {
221
- Object retval ;
238
+ SignalHandler oldHandler ;
222
239
try {
223
- retval = Signals .setSignalHandler (signum , id );
240
+ oldHandler = Signals .setSignalHandler (signum , id );
224
241
} catch (IllegalArgumentException e ) {
225
242
throw raise (PythonErrorType .TypeError , ErrorMessages .SIGNAL_MUST_BE_SIGIGN_SIGDFL_OR_CALLABLE_OBJ );
226
243
}
227
- if ((int ) retval == Signals .SIG_UNKNOWN ) {
228
- if (signalHandlers .containsKey (signum )) {
229
- retval = signalHandlers .get (signum );
230
- } else {
231
- retval = PNone .NONE ;
232
- }
233
- }
234
244
signalHandlers .put (signum , id );
235
- return retval ;
245
+ return handlerToPython (factory (), oldHandler , signum );
246
+ }
247
+
248
+ @ Specialization (limit = "1" )
249
+ Object signalHandler (@ SuppressWarnings ("unused" ) PythonModule self , Object signal , PJavaSignalHandler handler ,
250
+ @ CachedLibrary ("signal" ) PythonObjectLibrary signalLib ) {
251
+ int signum = signalLib .asSize (signal );
252
+ SignalHandler oldHandler ;
253
+ try {
254
+ oldHandler = Signals .setSignalHandler (signum , handler .getHandler ());
255
+ } catch (IllegalArgumentException e ) {
256
+ throw raise (PythonErrorType .ValueError , e );
257
+ }
258
+ signalHandlers .remove (signum );
259
+ return handlerToPython (factory (), oldHandler , signum );
236
260
}
237
261
238
262
@ Specialization (guards = "handlerLib.isCallable(handler)" , limit = "1" )
@@ -248,25 +272,18 @@ Object signalHandler(PythonModule self, Object signal, Object handler,
248
272
private Object signal (PythonModule self , int signum , Object handler , ReadAttributeFromObjectNode readQueueNode , ReadAttributeFromObjectNode readSemaNode ) {
249
273
ConcurrentLinkedDeque <SignalTriggerAction > queue = getQueue (self , readQueueNode );
250
274
Semaphore semaphore = getSemaphore (self , readSemaNode );
251
- Object retval ;
275
+ SignalHandler oldHandler ;
252
276
SignalTriggerAction signalTrigger = new SignalTriggerAction (handler , signum );
253
277
try {
254
- retval = Signals .setSignalHandler (signum , () -> {
278
+ oldHandler = Signals .setSignalHandler (signum , () -> {
255
279
queue .add (signalTrigger );
256
280
semaphore .release ();
257
281
});
258
282
} catch (IllegalArgumentException e ) {
259
283
throw raise (PythonErrorType .ValueError , e );
260
284
}
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
- }
268
285
signalHandlers .put (signum , handler );
269
- return retval ;
286
+ return handlerToPython ( factory (), oldHandler , signum ) ;
270
287
}
271
288
272
289
@ SuppressWarnings ("unchecked" )
@@ -288,6 +305,10 @@ private static Semaphore getSemaphore(PythonModule self, ReadAttributeFromObject
288
305
throw new IllegalStateException ("the signal trigger semaphore was modified!" );
289
306
}
290
307
}
308
+
309
+ protected static boolean isJavaHandler (Object obj ) {
310
+ return obj instanceof PJavaSignalHandler ;
311
+ }
291
312
}
292
313
}
293
314
@@ -299,7 +320,6 @@ private static Semaphore getSemaphore(PythonModule self, ReadAttributeFromObject
299
320
final class Signals {
300
321
static final int SIG_DFL = 0 ;
301
322
static final int SIG_IGN = 1 ;
302
- static final int SIG_UNKNOWN = -1 ;
303
323
private static final int SIGMAX = 31 ;
304
324
static final String [] signalNames = new String [SIGMAX + 1 ];
305
325
@@ -342,7 +362,7 @@ synchronized static void scheduleAlarm(long seconds) {
342
362
new Thread (new Alarm (seconds )).start ();
343
363
}
344
364
345
- private static class PythonSignalHandler implements sun .misc .SignalHandler {
365
+ static class PythonSignalHandler implements sun .misc .SignalHandler {
346
366
private final Runnable handler ;
347
367
348
368
public PythonSignalHandler (Runnable handler ) {
@@ -360,13 +380,17 @@ static String signalNumberToName(int signum) {
360
380
}
361
381
362
382
@ 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 );
383
+ synchronized static SignalHandler setSignalHandler (int signum , Runnable handler ) throws IllegalArgumentException {
384
+ return setSignalHandler (signum , new PythonSignalHandler (handler ));
385
+ }
386
+
387
+ @ TruffleBoundary
388
+ synchronized static SignalHandler setSignalHandler (int signum , SignalHandler handler ) throws IllegalArgumentException {
389
+ return sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), handler );
366
390
}
367
391
368
392
@ TruffleBoundary
369
- synchronized static int setSignalHandler (int signum , int handler ) throws IllegalArgumentException {
393
+ synchronized static SignalHandler setSignalHandler (int signum , int handler ) throws IllegalArgumentException {
370
394
sun .misc .SignalHandler h ;
371
395
if (handler == SIG_DFL ) {
372
396
h = sun .misc .SignalHandler .SIG_DFL ;
@@ -375,34 +399,24 @@ synchronized static int setSignalHandler(int signum, int handler) throws Illegal
375
399
} else {
376
400
throw new IllegalArgumentException ();
377
401
}
378
- return handlerToInt ( sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), h ) );
402
+ return sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), h );
379
403
}
380
404
381
405
@ TruffleBoundary
382
- synchronized static int getCurrentSignalHandler (int signum ) {
406
+ synchronized static SignalHandler getCurrentSignalHandler (int signum ) {
383
407
// To check what the current signal handler, we install default to get the current one
384
408
// and immediately replace it again.
385
409
sun .misc .SignalHandler oldH ;
386
410
try {
387
411
oldH = sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), sun .misc .SignalHandler .SIG_DFL );
388
412
} catch (IllegalArgumentException e ) {
389
- return SIG_DFL ;
413
+ return sun . misc . SignalHandler . SIG_DFL ;
390
414
}
391
415
try {
392
416
sun .misc .Signal .handle (new sun .misc .Signal (signalNumberToName (signum )), oldH );
393
417
} 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 ;
418
+ return sun .misc .SignalHandler .SIG_DFL ;
406
419
}
420
+ return oldH ;
407
421
}
408
422
}
0 commit comments