Skip to content

Commit 7768269

Browse files
committed
Thread#raise should call #exception in the target thread
* This is needed by Timeout.timeout in ruby/timeout#15 * Reuse Kernel#raise for convenience to both call #build_exception_for_raise and set the backtrace and print if $DEBUG.
1 parent ead4fa0 commit 7768269

File tree

4 files changed

+32
-5
lines changed

4 files changed

+32
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Compatibility:
2727
* Fix `Float#/` when dividing by `Rational` (@bjfish).
2828
* `Process.euid=` should accept String (#2615, @ngtban).
2929
* Fix `instance_variable_get` and `instance_variable_set` for immutable objects (@bjfish).
30+
* `Thread#raise(exc, message)` now calls `exc.exception` in the target thread like CRuby (@eregon).
3031

3132
Performance:
3233

spec/ruby/core/thread/raise_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,30 @@
102102
raised_again.backtrace.first.should_not include("#{__FILE__}:#{raise_again_line}:")
103103
end
104104
end
105+
106+
it "calls #exception in both the caller and in the target thread" do
107+
cls = Class.new(Exception) do
108+
attr_accessor :log
109+
def initialize(*args)
110+
@log = [] # This is shared because the super #exception uses a shallow clone
111+
super
112+
end
113+
114+
def exception(*args)
115+
@log << [self, Thread.current, args]
116+
super
117+
end
118+
end
119+
exc = cls.new
120+
121+
@thr.raise exc, "Thread#raise #exception spec"
122+
@thr.join
123+
ScratchPad.recorded.should.is_a?(cls)
124+
exc.log.should == [
125+
[exc, Thread.current, ["Thread#raise #exception spec"]],
126+
[ScratchPad.recorded, @thr, []]
127+
]
128+
end
105129
end
106130

107131
describe "Thread#raise on a running thread" do

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ private void setException(RubyThread thread, RubyException exception, Node curre
376376

377377
if (!isSystemExit && thread.reportOnException) {
378378
final TruffleSafepoint safepoint = TruffleSafepoint.getCurrent();
379-
380379
boolean sideEffects = safepoint.setAllowSideEffects(false);
381380
try {
382381
DispatchNode.getUncached().call(context.getCoreLibrary().truffleThreadOperationsModule,

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -858,11 +858,14 @@ public static void raiseInThread(RubyLanguage language, RubyContext context, Rub
858858
new SafepointAction("Thread#raise", rubyThread, true, false) {
859859
@Override
860860
public void run(RubyThread rubyThread, Node currentNode) {
861-
if (exception.backtrace == null) {
862-
exception.backtrace = context.getCallStack().getBacktrace(currentNode);
861+
final TruffleSafepoint safepoint = TruffleSafepoint.getCurrent();
862+
boolean sideEffects = safepoint.setAllowSideEffects(false);
863+
try {
864+
RubyContext.send(currentNode, rubyThread, "raise", exception);
865+
} finally {
866+
safepoint.setAllowSideEffects(sideEffects);
863867
}
864-
865-
VMRaiseExceptionNode.reRaiseException(context, exception);
868+
throw CompilerDirectives.shouldNotReachHere("#raise did not throw?");
866869
}
867870
});
868871
}

0 commit comments

Comments
 (0)