Issue #150 resolved

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

larskanis avatarlarskanis created an issue

When IO.for_fd(conn.socket) is used for instance to IO.select() 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: https://travis-ci.org/ged/ruby-pg/builds/4386997

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 conn.io 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. larskanis

    @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 > c=PGconn.new
    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 > c=PGconn.new
    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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.