Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

eventmachine fork test failure with rubinius #2044

Open
ttilley opened this Issue · 3 comments

3 participants

@ttilley

This one was fairly confusing because the individual test, when run by itself, passes just fine. The subprocess exits cleanly, the test can assert it received the text it expected from the subprocess via an IO.pipe, and all is well. However, when run after a test that calls into EM.error_handler, the forked process will not die.

This is a version of the test with just the two implicated factors: forking and EM.error_handler:

require 'em_test_helper'

class TestFork < Test::Unit::TestCase
  def test_error_handler_idempotent # issue 185
    errors = []
    ticks = []
    EM.error_handler do |e|
      errors << e
    end

    EM.run do
      EM.next_tick do
        ticks << :first
        raise
      end
      EM.next_tick do
        ticks << :second
      end
      EM.add_timer(0.001) { EM.stop }
    end

    assert_equal 1, errors.size
    assert_equal [:first, :second], ticks
  end

  def test_fork_safe
    return unless cpid = Process.fork { exit! } rescue false

    read, write = IO.pipe
    EM.run do
      cpid = Process.fork do
        write.puts "forked"
        EM.run do
          EM.next_tick do
            write.puts "EM ran"
            exit!
          end
        end
      end
      EM.stop
    end
    Process.waitall
    assert_equal "forked\n", read.readline
    assert_equal "EM ran\n", read.readline
  ensure
    read.close rescue nil
    write.close rescue nil
  end

end

If I add STDERR.puts debug statements, it does get as far as the exit! before hanging.

Due to what the error handler block actually DOES here, one could argue that the test is written poorly (and it is) to not remove the error handler as part of cleanup. In rubinius's case, that errors array is perhaps not kept alive by a reference from the block as it's passed into the EM C API?

@ttilley

Sure enough, adding an ensure block fixes the following test on rubinius:

  ensure
    EM.error_handler(nil)

I'm beginning to get curious about how this ends up working just fine on MRI18/MRI19.

@YorickPeterse

Seeing how this issue has been around for a while now, is there any need to keep it open? It's not entirely clear if this would be an Rbx issue, or if it has been fixed in the mean time.

@jc00ke
Owner

I added the ensure line and this test hangs. See this gist for the Ctrl+c segfaults.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.