public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
Fix double closing of file descriptors. This fixes some mysterious 
Errno::EBADF errors.
Hongli Lai (Phusion (author)
Sun Jun 08 08:38:18 -0700 2008
commit  68df948415004c96cd1c64b0a68b624e38243881
tree    e65b388374ea57cc0eaf2d355a54bdaa7a244ab5
parent  9e767bc6e3c1f1b7fac9f41d444ea104593035d9
...
17
18
19
 
20
21
22
...
113
114
115
116
 
 
 
 
 
 
 
 
 
 
 
117
118
119
...
17
18
19
20
21
22
23
...
114
115
116
 
117
118
119
120
121
122
123
124
125
126
127
128
129
130
0
@@ -17,6 +17,7 @@
0
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0
 
0
 require 'socket'
0
+require 'set'
0
 require 'timeout'
0
 require 'passenger/message_channel'
0
 require 'passenger/utils'
0
@@ -113,7 +114,17 @@ class AbstractServer
0
         STDOUT.sync = true
0
         STDERR.sync = true
0
         @parent_socket.close
0
- NativeSupport.close_all_file_descriptors([0, 1, 2, @child_socket.fileno])
0
+
0
+ # During Passenger's early days, we used to close file descriptors based
0
+ # on a white list of file descriptors. That proved to be way too fragile:
0
+ # too many file descriptors are being left open even though they shouldn't
0
+ # be. So now we close file descriptors based on a black list.
0
+ file_descriptors_to_close = [0, 1, 2, @child_socket.fileno]
0
+ NativeSupport.close_all_file_descriptors(file_descriptors_to_close)
0
+ # In addition to closing the file descriptors, one must also close
0
+ # the associated IO objects. This is to prevent IO.close from
0
+ # double-closing already closed file descriptors.
0
+ close_all_io_objects_for_fds(Set.new(file_descriptors_to_close))
0
         
0
         # At this point, RubyGems might have open file handles for which
0
         # the associated file descriptors have just been closed. This can
...
81
82
83
 
 
 
 
 
 
 
 
 
 
 
 
 
84
85
86
...
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
0
@@ -81,6 +81,19 @@ protected
0
     groupname && Etc.getgrnam(groupname)
0
   end
0
   
0
+ def close_all_io_objects_for_fds(file_descriptors_to_close)
0
+ ObjectSpace.each_object do |o|
0
+ if o.is_a?(IO)
0
+ begin
0
+ if o.closed? && file_descriptors_to_close.include?(o.fileno)
0
+ o.close
0
+ end
0
+ rescue
0
+ end
0
+ end
0
+ end
0
+ end
0
+
0
   def marshal_exception(exception)
0
     data = {
0
       :message => exception.message,

Comments

    No one has commented yet.