Skip to content

Commit d8a3928

Browse files
committed
Continue aborting if polling while aborting
If a thread is killed and then quickly interrupted in another way, it may end up polling for that other event and stop aborting from the kill. This ensures that once aborted a thread can never stop aborting by picking up a new interrupt event. This broke the new test server in test/mri/net/http/utils.rb when it killed the server and then closed the socket; while aborting the closed socket could trigger additional exceptions, stopping the abort. This ensures it will be seen at the next poll and resumed.
1 parent 112d82e commit d8a3928

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

core/src/main/java/org/jruby/RubyThread.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,13 +794,17 @@ public void pollThreadEvents(ThreadContext context, boolean blocking) {
794794

795795
// CHECK_INTS
796796
public void pollThreadEvents(ThreadContext context) {
797+
killIfAborting();
798+
797799
if (anyInterrupted()) {
798800
executeInterrupts(context, false);
799801
}
800802
}
801803

802804
// RUBY_VM_CHECK_INTS_BLOCKING
803805
public void blockingThreadPoll(ThreadContext context) {
806+
killIfAborting();
807+
804808
if (pendingInterruptQueue.isEmpty() && !anyInterrupted()) {
805809
return;
806810
}
@@ -810,6 +814,13 @@ public void blockingThreadPoll(ThreadContext context) {
810814
executeInterrupts(context, true);
811815
}
812816

817+
private void killIfAborting() {
818+
if (status == Status.ABORTING) {
819+
// currently aborting, resume abort
820+
throwThreadKill();
821+
}
822+
}
823+
813824
// RUBY_VM_INTERRUPTED_ANY
814825
private boolean anyInterrupted() {
815826
return Thread.interrupted() || (interruptFlag & ~interruptMask) != 0;

0 commit comments

Comments
 (0)