45
45
import java .util .List ;
46
46
import java .util .concurrent .ConcurrentHashMap ;
47
47
import java .util .concurrent .ConcurrentLinkedDeque ;
48
+ import java .util .concurrent .Semaphore ;
48
49
49
50
import com .oracle .graal .python .builtins .Builtin ;
50
51
import com .oracle .graal .python .builtins .CoreFunctions ;
@@ -77,6 +78,8 @@ public class SignalModuleBuiltins extends PythonBuiltins {
77
78
78
79
private static final HiddenKey signalQueueKey = new HiddenKey ("signalQueue" );
79
80
private final ConcurrentLinkedDeque <SignalTriggerAction > signalQueue = new ConcurrentLinkedDeque <>();
81
+ private static final HiddenKey signalSemaKey = new HiddenKey ("signalQueue" );
82
+ private final Semaphore signalSema = new Semaphore (0 );
80
83
81
84
@ Override
82
85
protected List <? extends NodeFactory <? extends PythonBuiltinBaseNode >> getNodeFactories () {
@@ -102,15 +105,18 @@ public void postInitialize(PythonCore core) {
102
105
103
106
PythonModule signalModule = core .lookupBuiltinModule ("_signal" );
104
107
signalModule .setAttribute (signalQueueKey , signalQueue );
108
+ signalModule .setAttribute (signalSemaKey , signalSema );
105
109
106
110
core .getContext ().registerAsyncAction (() -> {
107
- synchronized (signalQueue ) {
108
- try {
109
- signalQueue .wait ();
110
- } catch (InterruptedException e ) {
111
+ SignalTriggerAction poll = signalQueue .poll ();
112
+ try {
113
+ while (poll == null ) {
114
+ signalSema .acquire ();
115
+ poll = signalQueue .poll ();
111
116
}
117
+ } catch (InterruptedException e ) {
112
118
}
113
- return signalQueue . poll () ;
119
+ return poll ;
114
120
});
115
121
}
116
122
@@ -230,17 +236,17 @@ Object signal(@SuppressWarnings("unused") PythonModule self, long signalNumber,
230
236
@ Specialization
231
237
@ TruffleBoundary
232
238
Object signal (PythonModule self , long signalNumber , Object handler ,
233
- @ Cached ("create()" ) ReadAttributeFromObjectNode readNode ) {
239
+ @ Cached ("create()" ) ReadAttributeFromObjectNode readQueueNode ,
240
+ @ Cached ("create()" ) ReadAttributeFromObjectNode readSemaNode ) {
234
241
int signum = getSignum (signalNumber );
235
- ConcurrentLinkedDeque <SignalTriggerAction > queue = getQueue (self , readNode );
242
+ ConcurrentLinkedDeque <SignalTriggerAction > queue = getQueue (self , readQueueNode );
243
+ Semaphore semaphore = getSemaphore (self , readSemaNode );
236
244
Object retval ;
237
245
SignalTriggerAction signalTrigger = new SignalTriggerAction (handler , signum );
238
246
try {
239
247
retval = Signals .setSignalHandler (signum , () -> {
240
248
queue .add (signalTrigger );
241
- synchronized (queue ) {
242
- queue .notify ();
243
- }
249
+ semaphore .release ();
244
250
});
245
251
} catch (IllegalArgumentException e ) {
246
252
throw raise (PythonErrorType .ValueError , e );
@@ -266,6 +272,15 @@ private static ConcurrentLinkedDeque<SignalTriggerAction> getQueue(PythonModule
266
272
throw new IllegalStateException ("the signal trigger queue was modified!" );
267
273
}
268
274
}
275
+
276
+ private static Semaphore getSemaphore (PythonModule self , ReadAttributeFromObjectNode readNode ) {
277
+ Object semaphore = readNode .execute (self , signalSemaKey );
278
+ if (semaphore instanceof Semaphore ) {
279
+ return (Semaphore ) semaphore ;
280
+ } else {
281
+ throw new IllegalStateException ("the signal trigger semaphore was modified!" );
282
+ }
283
+ }
269
284
}
270
285
}
271
286
0 commit comments