Browse files

Make Thread#raise not raise $!

There is 1.8/1.9-specific behaviors when calling Thread#raise with no arguments
inside a rescue clause and the called thread is also inside a rescue clause.

First of all, Thread#raise doesn't use the exception in the calling thread. In
other words, Thread#raise doesn't use $!, only Kernel#raise does.

In 1.8, the raised exception is the exception in the called thread.

In 1.9, it is always a RuntimeError.
  • Loading branch information...
1 parent 788a5b0 commit c9160395f1f1877ed2ccf2dd7a22427d39616c73 @ryoqun ryoqun committed Oct 4, 2012
Showing with 25 additions and 1 deletion.
  1. +6 −1 kernel/bootstrap/thread.rb
  2. +4 −0 kernel/bootstrap/thread18.rb
  3. +4 −0 kernel/bootstrap/thread19.rb
  4. +5 −0 vm/builtin/thread.cpp
  5. +6 −0 vm/builtin/thread.hpp
View
7 kernel/bootstrap/thread.rb
@@ -71,6 +71,11 @@ def unlock_locks
Kernel.raise PrimitiveFailure, "Thread#unlock_locks primitive failed"
end
+ def current_exception
+ Rubinius.primitive :thread_current_exception
+ Kernel.raise PrimitiveFailure, "Thread#current_exception primitive failed"
+ end
+
@abort_on_exception = false
def self.abort_on_exception
@@ -245,7 +250,7 @@ def raise(exc=undefined, msg=nil, trace=nil)
begin
if exc.equal?(undefined)
no_argument = true
- exc = $!
+ exc = active_exception
end
if exc.respond_to? :exception
View
4 kernel/bootstrap/thread18.rb
@@ -130,4 +130,8 @@ def kill
def value
join_inner { @result }
end
+
+ def active_exception
+ current_exception
+ end
end
View
4 kernel/bootstrap/thread19.rb
@@ -114,4 +114,8 @@ def value
@killed ? nil : @result
end
end
+
+ def active_exception
+ nil
+ end
end
View
5 vm/builtin/thread.cpp
@@ -335,6 +335,11 @@ namespace rubinius {
return exc;
}
+ Object* Thread::current_exception(STATE) {
+ utilities::thread::SpinLock::LockGuard lg(init_lock_);
+ return vm_->thread_state()->current_exception();
+ }
+
Object* Thread::kill(STATE, GCToken gct) {
utilities::thread::SpinLock::LockGuard lg(init_lock_);
Thread* self = this;
View
6 vm/builtin/thread.hpp
@@ -167,6 +167,12 @@ namespace rubinius {
Object* raise(STATE, GCToken gct, Exception* exc);
/**
+ * Returns current exception
+ */
+ // Rubinius.primitive :thread_current_exception
+ Object* current_exception(STATE);
+
+ /**
* Kill this Thread.
*/
// Rubinius.primitive :thread_kill

0 comments on commit c916039

Please sign in to comment.