lib/pitchfork/info.rb in pitchfork-0.6.0 vs lib/pitchfork/info.rb in pitchfork-0.7.0

- old
+ new

@@ -3,12 +3,60 @@ require 'pitchfork/shared_memory' module Pitchfork module Info @workers_count = 0 + @fork_safe = true + @kept_ios = ObjectSpace::WeakMap.new class << self attr_accessor :workers_count + + def keep_io(io) + raise ArgumentError, "#{io.inspect} doesn't respond to :to_io" unless io.respond_to?(:to_io) + @kept_ios[io] = io + io + end + + def keep_ios(ios) + ios.each { |io| keep_io(io) } + end + + def close_all_ios! + ignored_ios = [$stdin, $stdout, $stderr] + + @kept_ios.each_value do |io_like| + ignored_ios << (io_like.is_a?(IO) ? io_like : io_like.to_io) + end + + ObjectSpace.each_object(IO) do |io| + closed = begin + io.closed? + rescue IOError + true + end + + if !closed && io.autoclose? && !ignored_ios.include?(io) + if io.is_a?(TCPSocket) + # If we inherited a TCP Socket, calling #close directly could send FIN or RST. + # So we first reopen /dev/null to avoid that. + io.reopen(File::NULL) + end + begin + io.close + rescue Errno::EBADF + end + end + end + end + + def fork_safe? + @fork_safe + end + + def no_longer_fork_safe! + @fork_safe = false + end def live_workers_count now = Pitchfork.time_now(true) (0...workers_count).count do |nr| SharedMemory.worker_deadline(nr).value > now