Project

General

Profile

Actions

Bug #4285

closed

Ruby don't have asynchrounous exception safe syntax and It should have.

Added by kosaki (Motohiro KOSAKI) about 10 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Target version:
ruby -v:
ruby 1.9.3dev (2010-12-22 trunk 30291) [x86_64-linux]
Backport:
[ruby-core:34537]

Description

=begin
This issue was discovered during [Bug#4266] discussion.
Current timeout is racy.

Now, timeout module has following code.


def timeout()
begin
x = Thread.current
y = Thread.start {
begin
sleep sec
rescue => e
x.raise e
else
x.raise exception, "execution expired" if x.alive?
end
}
return yield(sec)
rescue exception => e
raise Error, e.message, e.backtrace
ensure
if y and y.alive?
y.kill
y.join # make sure y is dead.
end
end
end


Unfortunatelly,

y = Thread.start {}

is not an atomic operation. Then, A following race can occur.

CPU0(thread x) CPU1(thread y) remark


enter begin block
[thread construct] but no assign y yet
sleep sec
wakeup from sleep
x.raise
if y return false. (see above)

Therefore, CPU0 don't call y.join and leak y's thread resource. C# have solved
this two-step-construction vs asynchrounous exception race by RAII.
(Plus, C#'s finally block is async exception safe automatically)

But unfortunately, Ruby don't have such language feature. So, We can't write
async-exception-safe code. One of solution is to move timeout module from ruby code
into c code as JRuby does. But I don't think timeout is only asynchrounos exception user.
we also have Interrupt class (for Ctrl-C) and I think we need to allow to write async
exception safe code by ruby.

So, My proposal is,
o for 1.9.x
=> Reimplement timeout.rb by C (as JRuby)

o for 2.0
=> Aim new feature for writing async exception safe code.

Or, Am I missing something?
=end


Files

timeout.rb.diff (1.12 KB) timeout.rb.diff mwaechter (Matthias Wächter), 01/18/2011 02:36 AM
timeout.rb.diff (1.12 KB) timeout.rb.diff mwaechter (Matthias Wächter), 01/18/2011 02:36 AM

Related issues

Related to Ruby master - Bug #4266: Timeouts in threads cause "ThreadError: deadlock; recursive locking"Closedkosaki (Motohiro KOSAKI)01/12/2011Actions
Related to Ruby master - Bug #4283: Timeout.timeout may cause application exit unintetionallyClosedmatz (Yukihiro Matsumoto)01/17/2011Actions
Related to Ruby master - Feature #3251: allow to unlock mutex locked by another threadRejectedko1 (Koichi Sasada)05/06/2010Actions
Related to Ruby master - Feature #1952: cannot stop with Ctrl+CClosedko1 (Koichi Sasada)08/18/2009Actions
Is duplicate of Ruby master - Feature #6762: Control interrupt timingClosedko1 (Koichi Sasada)07/21/2012Actions
Actions

Also available in: Atom PDF