IO.for_fd(conn.socket) may cause EBADF on the connection

Issue #150 resolved
Lars Kanis created an issue

When IO.for_fd(conn.socket) is used for instance to on the database connection, it might happen that the allocated IO gets GC'ed and the sockets gets closed therefore. A subsequent SQL statement will then fail. Contrary the PG::Connection might be closed before the IO gets GC'ed. This is the cause for the spec errors in:

On Ruby-1.9.3 the IO should generally be build with IO#autoclose=false. But on Ruby-1.8.7 there is no autoclose. The only way seems to store the IO object somewhere to avoid GC'ing, there.

How should we deal with this issue? My ideas are:

  1. We could run the test cases with IO.for_fd only on 1.9.3 with autoclose=false and describe the issue in conn.socket.

  2. We could add a new method that returns a IO object, that doesn't get GC'ed before PQfinish. Maybe someday someone will figure out how we could bind a socket file descriptor to an IO on Windows, so that it gets usable there, too.

  3. We could ensure that the IO is not GC'ed within the specs.

Comments (8)

  1. Lars Kanis reporter

    @socket_io needs to be closed on #finish, too, to avoid that a file descriptor with accadantly the same value is closed on the next GC run. This is easiely reproducable:

    $ irb -rubygems -rpg
    1.8.7 :001 >
    1.8.7 :002 > c.socket_io  # => #<IO:0x7f3304e88878> 
    1.8.7 :003 > c.exec 'select 1'  # => #<PG::Result:0x7f3304f7f178> 
    1.8.7 :004 > c.close
    1.8.7 :005 >
    1.8.7 :006 > c.socket_io  # => #<IO:0x7f3304f6b8f8> 
    1.8.7 :007 > GC.start
    1.8.7 :008 > c.exec 'select 1'  # PG::Error: could not receive data from server: Bad file descriptor
  2. Log in to comment