Project

General

Profile

Actions

Bug #6822

closed

Race Condition with Fiber and Process

Added by MartinBosslet (Martin Bosslet) over 12 years ago. Updated about 12 years ago.

Status:
Closed
Target version:
ruby -v:
ruby 2.0.0dev (2012-05-07 trunk 35550) [x86_64-linux]
Backport:
[ruby-core:46922]

Description

If I run the following code

$stdout.sync = true
objects = [1, 2, 3]

fiber = Fiber.new do
  loop do
    objects.each { |obj| Fiber.yield(obj) }
  end
end

def run(obj)
  fork do
    puts obj
  end
end

def on_child_exit(obj)
  begin
    while Process.wait(-1, Process::WNOHANG)
      run(obj)
    end
  rescue Errno::ECHILD
  end
end

trap(:CHLD) { on_child_exit(fiber.resume) }
4.times { run(fiber.resume) }
sleep

I get

fiber_process.rb:26:in `resume': double resume (FiberError)

or

fiber_process.rb:26:in `resume': fiber called across stack rewinding barrier (FiberError)

There is a race condition when two or more children exit. Now I know I can implement
this differently, but this still made me curious. Is this a bug? Let's say I would
need to use a Fiber, then there is no way how I can do the synchronization manually,
or is there? Using a Mutex to synchronize the Fiber#resume will fail due to the
non-reentrant behaviour of Mutex#lock (I'll get "in `lock': deadlock; recursive
locking (ThreadError)"). Is there a way to do this or should Fibers not be used in
this context?

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0