From: SASADA Koichi Date: 2011-07-02T10:17:57+09:00 Subject: [ruby-core:37727] Issue of Passenger and ruby-trunk Hi, We received a bug report ([ruby-dev:44011] [Ruby 1.9 - Bug #4958], in Japanese) that says Passenger (*1) doesn't work with current trunk. I surveyed it and found out the reason. *1: http://www.modrails.com/ In short, Passenger close most of file descriptors (fd) by NativeSupport.close_all_file_descriptors(). However, current Ruby uses 2 fds for to communicate between [signal handler] <-> [timer thread] <-> [ruby thread]. I can run Passenger on commented out "NativeSupport.close_all_file_descriptors" line. Details: (1) Ruby-side: To avoid timer thread frequent invocation, we modified them totally. And we decided to use pipe to communicate between [signal handler] <-> [timer thread] <-> [ruby thread]. We named this pipe "communication pipe". Ruby opens pipe at first. Ruby also open pipe after fork(). (2) Passenger-side: I assume that Passenger fork ruby process if request reached. At first, forked process close all file descriptors to avoid file descriptor leak. The method NativeSupport.close_all_file_descriptors(left_fds) forcibly closes all file descriptors except left_fds. quoted from passenger-3.0.5/lib/phusion_passenger/abstract_server.rb: > # During Passenger's early days, we used to close file descriptors based > # on a white list of file descriptors. That proved to be way too fragile: > # too many file descriptors are being left open even though they shouldn't > # be. So now we close file descriptors based on a black list. > # > # Note that STDIN, STDOUT and STDERR may be temporarily set to > # different file descriptors than 0, 1 and 2, e.g. in unit tests. > # We don't want to close these either. > file_descriptors_to_leave_open = [0, 1, 2, > b.fileno, server_socket.fileno, > fileno_of(STDIN), fileno_of(STDOUT), fileno_of(STDERR) > ].compact.uniq > NativeSupport.close_all_file_descriptors(file_descriptors_to_leave_open) (3) Problem NativeSupport.close_all_file_descriptors(file_descriptors_to_leave_open) closes communication pipe. It causes critical problem to run ruby. For exmaple, in report [ruby-dev:44011] [Ruby 1.9 - Bug #4958], the following [BUG] was reported. > /var/log/httpd/error_log: > ------- > [ASYNC BUG] thread_timer: select > EBADF > > ruby 1.9.3dev (2011-07-01 trunk 32348) [x86_64-linux] > > [NOTE] > You may have encountered a bug in the Ruby interpreter or extension libraries. > Bug reports are welcome. > For details: http://www.ruby-lang.org/bugreport.html > ----- I confirmed that I commented out the line NativeSupport.close_all_file_descriptors, then Passenger run normally. (4) Solution How to solve it? May I provide some C API or Ruby API to get pipe fds? -- // SASADA Koichi at atdot dot net