Permalink
Browse files

Fix handling of :how => :partial once the process is dead

  • Loading branch information...
1 parent 0151887 commit 186f63ebee3813e663ef98ae0f70a1810ea5fa51 @gdb committed Oct 14, 2013
Showing with 32 additions and 1 deletion.
  1. +7 −1 lib/rubysh/runner.rb
  2. +7 −0 lib/rubysh/subprocess/pid_aware_parallel_io.rb
  3. +18 −0 test/functional/lib/read.rb
View
@@ -56,9 +56,15 @@ def read(target=nil, opts=nil)
case how = opts[:how]
when :partial
# Read until we get some bytes
- @parallel_io.run_once until state[:buffer].length != state[:read_pos]
+ while state[:buffer].length == state[:read_pos]
+ # If everything's exited, just return nil
+ return nil if @parallel_io.finalized
+ @parallel_io.run_once
+ end
when :nonblock
@parallel_io.read_available(state[:target])
+ # Return nil unless we have something new
+ return nil if state[:buffer].length == state[:read_pos]
when nil
communicate if @runner_state == :started
else
@@ -58,10 +58,13 @@ def self.deregister_sigchld_handler
Signal.trap('CHLD', @old_sigchld_handler)
end
+ attr_reader :finalized
+
# readers/writers should be hashes mapping {fd => name}
def initialize(readers, writers, subprocesses)
@breaker_reader, @breaker_writer = IO.pipe
@subprocesses = subprocesses
+ @finalized = false
readers = readers.dup
readers[@breaker_reader] = nil
@@ -75,6 +78,8 @@ def register_subprocesses
end
def run_once(timeout=nil)
+ return if @finalized
+
@subprocesses.each do |subprocess|
subprocess.wait(true)
end
@@ -98,6 +103,8 @@ def finalize_all
available_readers.each {|reader| reader.close}
available_writers.each {|writer| writer.close}
self.class.deregister_parallel_io(self)
+
+ @finalized = true
end
end
end
@@ -0,0 +1,18 @@
+require File.expand_path('../_lib', File.dirname(__FILE__))
+
+module RubyshTest::Functional
+ class ReadTest < FunctionalTest
+ describe 'when reading with :how => :partial' do
+ it 'returns nil once the process is dead' do
+ runner = Rubysh('ruby', '-e', 'puts "hi"', Rubysh.>).run_async
+
+ # Pump stdout
+ while runner.read(:how => :partial)
+ end
+
+ runner.wait
+ assert_equal(nil, runner.read(:how => :partial))
+ end
+ end
+ end
+end

0 comments on commit 186f63e

Please sign in to comment.