[#62904] [ruby-trunk - Feature #9894] [Open] [RFC] README.EXT: document rb_gc_register_mark_object — normalperson@...
Issue #9894 has been reported by Eric Wong.
3 messages
2014/06/02
[#63321] [ANN] ElixirConf 2014 - Don't Miss Jos辿 Valim and Dave Thomas — Jim Freeze <jimfreeze@...>
Just a few more weeks until ElixirConf 2014!
6 messages
2014/06/24
[ruby-core:62897] [ruby-trunk - Bug #9447] Bad interaction between Fibers and Trap handlers in Ruby > 2.0.0
From:
xkernigh@...
Date:
2014-06-01 01:30:34 UTC
List:
ruby-core #62897
Issue #9447 has been updated by George Koehler.
I found this bug report while searching for another bug.
This seems a bug in the Alarm implementation, not a bug in Ruby. *Alarm::alarm* pauses the fiber in the trap, so it never left trap context. The fix is to escape the trap with *raise* or *throw* or a simple *return*.
I made three revisions.
1. Remove the version number from 'libc.so', so it can find libc.so.73 in my OpenBSD system.
2. Switch to Fiddle::Importer, to avoid the message "DL is deprecated, please use Fiddle"
3. Use *return* to escape the trap.
It still fails if the signal comes to the wrong thread. The old code would yield from the wrong fiber, probably raising "can't yield from root fiber (FiberError)". The new code would raise "unexpected return (LocalJumpError)".
Here is my revised code:
~~~
require 'fiddle'
require 'fiddle/import'
module Alarm
module SystemCall
extend Fiddle::Importer
# imports the POSIX alarm function
begin
dlload 'libc.so'
rescue
dlload 'libc.dylib'
end
extern 'unsigned int alarm(unsigned int)'
end
def self.alarm(n)
# new signal handler for the alarm call
handler = Signal.trap('ALRM') do
# returns from this function
return
end
# start timing
SystemCall.alarm(n)
# start running timed call
return yield
ensure
# cancel alarms and restore the previous signal handler
SystemCall.alarm(0)
Signal.trap('ALRM', handler)
end
end
~~~
Here is a test program:
~~~
require_relative 'alarm'
Alarm.alarm(4) do
1.step {|i| sleep 1; puts i }
end
puts "Got the alarm!"
Mutex.new.synchronize { puts "Got the mutex!" }
~~~
----------------------------------------
Bug #9447: Bad interaction between Fibers and Trap handlers in Ruby > 2.0.0
https://bugs.ruby-lang.org/issues/9447#change-46993
* Author: Nilson Santos Figueiredo Junior
* Status: Open
* Priority: Normal
* Assignee:
* Category:
* Target version:
* ruby -v: ruby 2.0.0p247
* Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN
----------------------------------------
Hi there,
I've been using and Alarm class I created, which gives Ruby code access to the alarm system call.
It used to work perfectly on 1.9.3 with no issues and more than 1 year of production usage.
Ruby 2.0.0 doesn't let me use it properly, apparently when there's an alarm timeout, the interpreter will think the code is in the trap context forever, so when I try to use Logger afterwards, it will fail (since it uses a Mutex internally).
Below is my Alarm implementation.
require 'dl'
require 'dl/import'
module Alarm
module SystemCall
extend DL::Importer
# imports the POSIX alarm function
begin
dlload 'libc.so.6'
rescue
begin
dlload 'libc.so.5'
rescue
dlload 'libc.dylib'
end
end
extern 'unsigned int alarm(unsigned int)'
end
def self.alarm(n)
# creates new fiber which will the code block passed as argument
fiber = Fiber.new { yield }
begin
# new signal handler for the alarm call
handler = Signal.trap('ALRM') do
# yields fiber, which makes the control flow continue after
# after the last resume call for this fiber
# (in other words, returns from this function)
Fiber.yield
end
# start timing
SystemCall.alarm(n)
# start running timed call
result = fiber.resume
ensure
# cancel alarms and restore the previous signal handler
SystemCall.alarm(0)
Signal.trap('ALRM', handler)
end
return result
end
end
Is this sort of thing really no longer supported in Ruby > 2.0.0 or is it a bug? As I've said, it worked perfectly on 1.9.3.
This class is used like this:
Alarm.alarm(timeout_seconds) do
# potentially time consuming operation which must have a timeout
end
Due to other requirements, I can't use the Timeout module, as it creates another thread.
Thanks in advance.
--
https://bugs.ruby-lang.org/