chuckremes / ffi-rzmq

FFI bindings for ZeroMQ so the library can be used under JRuby and other FFI-compliant ruby runtimes
242 stars 62 forks source link

Bad file descriptor #90

Closed quixoten closed 11 years ago

quixoten commented 11 years ago

This might be an issue with the ZMQ library itself, but I wanted to post it here first.

Running the following code produces a "Bad file descriptor" error on my linux machine running ZMQ version 3.2.3. It also happens on OSX running ZMQ version 3.2.2. It appears to be caused by creating/destroying many contexts and sockets in rapid succession in different threads.

Using a single context for all the requests removes the error. Creating/destroying the contexts and sockets synchronously removes the error as well.

require 'ffi-rzmq'

server = Thread.new do
  zmq_context = ZMQ::Context.new
  socket = zmq_context.socket(ZMQ::REP)
  rc = socket.bind("tcp://127.0.0.1:55020")
  poller = ZMQ::Poller.new
  poller.register_readable(socket)

  begin
    while poller.poll == 1
      socket.recv_string(message = "")
      print "server rcvd: #{message}\n"
      socket.send_string(message)
    end
  ensure
    socket.close
    zmq_context.terminate
  end
end

100.times do |x|
  100.times.map do |y|
    Thread.new do
      zmq_context = ZMQ::Context.new
      socket = zmq_context.socket(ZMQ::REQ)
      rc = socket.connect("tcp://127.0.0.1:55020")

      socket.send_string("#{x}, #{y}")
      socket.recv_string(reply = "")
      socket.close
      zmq_context.terminate
    end
  end.each(&:join)
end

server.kill
quixoten commented 11 years ago

From the ZMQ Guide:

If you are opening and closing a lot of sockets, that's probably a sign that you need to redesign your application. In some cases socket handles won't be freed until you destroy the context.

I'm satisfied that ZMQ is not meant to operate in this way.