4545import java .util .List ;
4646import java .util .concurrent .ConcurrentHashMap ;
4747import java .util .concurrent .ConcurrentLinkedDeque ;
48+ import java .util .concurrent .Semaphore ;
4849
4950import com .oracle .graal .python .builtins .Builtin ;
5051import com .oracle .graal .python .builtins .CoreFunctions ;
@@ -77,6 +78,8 @@ public class SignalModuleBuiltins extends PythonBuiltins {
7778
7879 private static final HiddenKey signalQueueKey = new HiddenKey ("signalQueue" );
7980 private final ConcurrentLinkedDeque <SignalTriggerAction > signalQueue = new ConcurrentLinkedDeque <>();
81+ private static final HiddenKey signalSemaKey = new HiddenKey ("signalQueue" );
82+ private final Semaphore signalSema = new Semaphore (0 );
8083
8184 @ Override
8285 protected List <? extends NodeFactory <? extends PythonBuiltinBaseNode >> getNodeFactories () {
@@ -102,15 +105,18 @@ public void postInitialize(PythonCore core) {
102105
103106 PythonModule signalModule = core .lookupBuiltinModule ("_signal" );
104107 signalModule .setAttribute (signalQueueKey , signalQueue );
108+ signalModule .setAttribute (signalSemaKey , signalSema );
105109
106110 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 ();
111116 }
117+ } catch (InterruptedException e ) {
112118 }
113- return signalQueue . poll () ;
119+ return poll ;
114120 });
115121 }
116122
@@ -230,17 +236,17 @@ Object signal(@SuppressWarnings("unused") PythonModule self, long signalNumber,
230236 @ Specialization
231237 @ TruffleBoundary
232238 Object signal (PythonModule self , long signalNumber , Object handler ,
233- @ Cached ("create()" ) ReadAttributeFromObjectNode readNode ) {
239+ @ Cached ("create()" ) ReadAttributeFromObjectNode readQueueNode ,
240+ @ Cached ("create()" ) ReadAttributeFromObjectNode readSemaNode ) {
234241 int signum = getSignum (signalNumber );
235- ConcurrentLinkedDeque <SignalTriggerAction > queue = getQueue (self , readNode );
242+ ConcurrentLinkedDeque <SignalTriggerAction > queue = getQueue (self , readQueueNode );
243+ Semaphore semaphore = getSemaphore (self , readSemaNode );
236244 Object retval ;
237245 SignalTriggerAction signalTrigger = new SignalTriggerAction (handler , signum );
238246 try {
239247 retval = Signals .setSignalHandler (signum , () -> {
240248 queue .add (signalTrigger );
241- synchronized (queue ) {
242- queue .notify ();
243- }
249+ semaphore .release ();
244250 });
245251 } catch (IllegalArgumentException e ) {
246252 throw raise (PythonErrorType .ValueError , e );
@@ -266,6 +272,15 @@ private static ConcurrentLinkedDeque<SignalTriggerAction> getQueue(PythonModule
266272 throw new IllegalStateException ("the signal trigger queue was modified!" );
267273 }
268274 }
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+ }
269284 }
270285}
271286
0 commit comments