Permalink
Browse files

Merge pull request #1942 from ryoqun/thread-raise-rescue

Make Thread#raise not raise $!
  • Loading branch information...
2 parents 5d89b8a + ac94dc2 commit 5c9506bedd88e399733bc0cf3ab4127c7542da2e @dbussink dbussink committed Oct 29, 2012
@@ -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
@@ -130,4 +130,8 @@ def kill
def value
join_inner { @result }
end
+
+ def active_exception
+ current_exception
+ end
end
@@ -114,4 +114,8 @@ def value
@killed ? nil : @result
end
end
+
+ def active_exception
+ nil
+ end
end
@@ -52,13 +52,32 @@
lambda { t.value }.should raise_error(RuntimeError)
end
+ ruby_version_is "" ... "1.9" do
+ it "raises a ZeroDivisionError when called with no arguments inside rescue" do
+ t = Thread.new do
+ begin
+ 1/0
+ rescue ZeroDivisionError
+ sleep
+ end
+ end
+ begin
+ raise RangeError
+ rescue
+ ThreadSpecs.spin_until_sleeping(t)
+ t.raise
+ end
+ lambda {t.value}.should raise_error(ZeroDivisionError)
+ end
+ end
+
ruby_version_is "1.9" do
- it "raises a RuntimeError when called with no arguments" do
+ it "raises a RuntimeError when called with no arguments inside rescue" do
t = Thread.new do
begin
1/0
rescue ZeroDivisionError
- sleep 3
+ sleep
end
end
begin
@@ -68,7 +87,6 @@
t.raise
end
lambda {t.value}.should raise_error(RuntimeError)
- t.kill
end
end
end
@@ -127,14 +145,81 @@
begin
raise "Create an active exception for the current thread too"
rescue
- Thread.pass until raised || !t.alive?
+ Thread.pass until raised
t.raise RangeError
lambda {t.value}.should raise_error(RangeError)
end
end
+ ruby_version_is "" ... "1.9" do
+ it "raises a ZeroDivisionError when called with no arguments inside rescue" do
+ raised = false
+ t = Thread.new do
+ begin
+ 1/0
+ rescue ZeroDivisionError
+ raised = true
+ loop { }
+ end
+ end
+ begin
+ raise RangeError
+ rescue
+ Thread.pass until raised
+ t.raise
+ end
+ lambda {t.value}.should raise_error(ZeroDivisionError)
+ end
+ end
+
+ ruby_version_is "1.9" do
+ it "raises a RuntimeError when called with no arguments inside rescue" do
+ raised = false
+ t = Thread.new do
+ begin
+ 1/0
+ rescue ZeroDivisionError
+ raised = true
+ loop { }
+ end
+ end
+ begin
+ raise RangeError
+ rescue
+ Thread.pass until raised
+ t.raise
+ end
+ lambda {t.value}.should raise_error(RuntimeError)
+ end
+ end
end
describe "Thread#raise on same thread" do
it_behaves_like :kernel_raise, :raise, Thread.current
+
+ ruby_version_is "" ... "1.9" do
+ it "raises a ZeroDivisionError when called with no arguments inside rescue" do
+ t = Thread.new do
+ begin
+ 1/0
+ rescue ZeroDivisionError
+ Thread.current.raise
+ end
+ end
+ lambda {t.value}.should raise_error(ZeroDivisionError)
+ end
+ end
+
+ ruby_version_is "1.9" do
+ it "raises a RuntimeError when called with no arguments inside rescue" do
+ t = Thread.new do
+ begin
+ 1/0
+ rescue ZeroDivisionError
+ Thread.current.raise
+ end
+ end
+ lambda {t.value}.should raise_error(RuntimeError)
+ end
+ end
end
@@ -1,2 +1 @@
-fails:Thread#raise on a sleeping thread raises a RuntimeError when called with no arguments
unstable:Thread#raise on a running thread raises a RuntimeError if no exception class is given
@@ -1,2 +1 @@
-fails:Thread#raise on a sleeping thread raises a RuntimeError when called with no arguments
unstable:Thread#raise on a running thread raises a RuntimeError if no exception class is given
View
@@ -336,6 +336,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
@@ -172,6 +172,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 5c9506b

Please sign in to comment.