Skip to content

Commit aacd319

Browse files
committed
Ensure the NativeCallInterrupter task is never executed after it is cancelled
1 parent 2fa8bdf commit aacd319

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

src/main/java/org/truffleruby/core/thread/NativeCallInterrupter.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,39 @@ static class Task extends TimerTask {
5050

5151
private final long threadID;
5252
private int executed = 0;
53+
private boolean cancelled = false;
5354

5455
Task(long threadID) {
5556
this.threadID = threadID;
5657
}
5758

59+
@Override
60+
public boolean cancel() {
61+
// Ensure this task does not run later when this method returns.
62+
// If it was running at the time of cancel(), wait for that.
63+
synchronized (this) {
64+
cancelled = true;
65+
return super.cancel();
66+
}
67+
}
68+
5869
@Override
5970
public void run() {
60-
if (executed < MAX_EXECUTIONS) {
61-
executed++;
62-
int result = LibRubySignal.sendSIGVTALRMToThread(threadID);
63-
if (result != 0) {
64-
throw CompilerDirectives.shouldNotReachHere(
65-
String.format("pthread_kill(%x, SIGVTALRM) failed with result=%d", threadID, result));
71+
synchronized (this) {
72+
if (cancelled) {
73+
return;
74+
}
75+
76+
if (executed < MAX_EXECUTIONS) {
77+
executed++;
78+
int result = LibRubySignal.sendSIGVTALRMToThread(threadID);
79+
if (result != 0) {
80+
throw CompilerDirectives.shouldNotReachHere(
81+
String.format("pthread_kill(%x, SIGVTALRM) failed with result=%d", threadID, result));
82+
}
83+
} else {
84+
cancel();
6685
}
67-
} else {
68-
cancel();
6986
}
7087
}
7188
}

0 commit comments

Comments
 (0)